#include <iostream>
#include <stdlib.h>
#include <processthreadsapi.h>
#include <Windows.h>
#include <semaphore.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <stdarg.h>
#include <strsafe.h>
void ErrorExit(LPTSTR lpszFunction)
{
// Retrieve the system error message for the last-error code
LPVOID lpMsgBuf;
LPVOID lpDisplayBuf;
DWORD dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &lpMsgBuf,
0, NULL );
// Display the error message and exit the process
lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
(lstrlen((LPCTSTR)lpMsgBuf) + lstrlen((LPCTSTR)lpszFunction) + 40) * sizeof(TCHAR));
StringCchPrintf((LPTSTR)lpDisplayBuf,
LocalSize(lpDisplayBuf) / sizeof(TCHAR),
TEXT("%s failed with error %d: %s"),
lpszFunction, dw, lpMsgBuf);
MessageBox(NULL, (LPCTSTR)lpDisplayBuf, TEXT("Error"), MB_OK);
LocalFree(lpMsgBuf);
LocalFree(lpDisplayBuf);
ExitProcess(dw);
}
typedef struct {
sem_t edited;
sem_t sus;
sem_t running;
} sem_res_sus;
sem_res_sus sem_rs;
int checked = 0;
int isSuspend = 0;
int rollbackPoint = -1;
// producer
DWORD WINAPI thread(LPVOID arg) {
// edited isSuspend to 1 then can running and then suspended by the process
sem_wait(&sem_rs.edited);
sem_post(&sem_rs.sus);
while(isSuspend);
sem_post(&sem_rs.running);
std::cout << "thread resume from sus!" << std::endl;
sem_wait(&sem_rs.edited);
sem_post(&sem_rs.sus);
while(isSuspend);
sem_post(&sem_rs.running);
std::cout << "thread resume from sus again!" << std::endl;
return EXIT_SUCCESS;
}
DWORD WINAPI scheduler(LPVOID arg) {
CONTEXT a[2];
a[0].ContextFlags = CONTEXT_ALL;
a[1].ContextFlags = CONTEXT_ALL;
HANDLE hThread = (HANDLE) arg;
while(checked < 2) {
sem_wait(&sem_rs.running);
isSuspend = 1;
// edited isSuspend to 1 tell thread can running and then suspended by the process
sem_post(&sem_rs.edited);
// The process wait thread to tell him it can be suspended
sem_wait(&sem_rs.sus);
if (SuspendThread(hThread) == -1) {
ErrorExit(TEXT("SuspendThread"));
}
if (GetThreadContext(hThread, &a[checked]) == 0) {
ErrorExit(TEXT("GetThreadContext"));
}
if (checked == 1) { // 假设此时发生错误
// 回退到上一个检查点后,需要记录该次回卷点。
rollbackPoint = 0;
if (SetThreadContext(hThread, &a[0]) == 0) {
ErrorExit(TEXT("SetThreadContext"));
}
} else {
rollbackPoint = -1;
}
if(ResumeThread(hThread) == -1) {
ErrorExit(TEXT("ResumeThread"));
} else {
isSuspend = 0;
}
checked++;
if (rollbackPoint != -1) {
// 若回退了
checked = rollbackPoint + 1;
rollbackPoint = -1;
}
}
}
int main() {
sem_init(&sem_rs.edited, 0, 0);
sem_init(&sem_rs.sus, 0, 0);
sem_init(&sem_rs.running, 0, 1);
DWORD t;
std::cout << "start execution" << std::endl;
HANDLE hThread = CreateThread(
NULL,
0,
thread,
NULL,
0,
&t
);
DWORD t_h;
HANDLE control_hThread = CreateThread(
NULL,
0,
scheduler,
hThread,
0,
&t_h
);
WaitForSingleObject(hThread, INFINITE);
WaitForSingleObject(control_hThread, INFINITE);
CloseHandle(hThread);
sem_close(&sem_rs.sus);
sem_close(&sem_rs.edited);
return EXIT_SUCCESS;
}
The above is my code. In some random number of rounds, it works fine and print "thread resume from sus!" regularly. But then it will blocked thread blocked at sem_post(&sem_rs.sus); scheduler blocked at sem_wait(&sem_rs.sus) How to solve this issues? Thanks
I am searching for why, but nothing helpful.