Program below is a synchronization between two threads using a Mutex.
It compiles, works and prints what I want in order(alternating R/W for the 2 threads), but it crashes after it's done. Any idea why?
I think it has to do with closing TName
handle, if I comment that part it doesn't crash, but I'd like to close opened handles.
HANDLE hMutex, hWriteDone, hReadDone;
int num, state;
void Writer()
{
for(int x=10; x>=0; x--)
{
while (true)
{
if (WaitForSingleObject(hMutex, INFINITE) == WAIT_FAILED)
{
std::cout<<"In writing loop, no mutex!\n";
ExitThread(0);
}
if (state == 0)
{
ReleaseMutex(hMutex);
WaitForSingleObject(hReadDone, INFINITE);
continue;
}
break;
}
std::cout<<"Write done\n";
num= x;
state= 0;
ReleaseMutex(hMutex);
PulseEvent(hWriteDone);
}
}
void Reader()
{
while(true)
{
if (WaitForSingleObject(hMutex, INFINITE) == WAIT_FAILED)
{
std::cout<<"In reader, no mutex!\n";
ExitThread(0);
}
if (state == 1)
{
ReleaseMutex(hMutex);
WaitForSingleObject(hWriteDone, INFINITE);
continue;
}
if (num == 0)
{
std::cout<<"End of data\n";
ReleaseMutex(hMutex);
ExitThread(0);
}
else {
std::cout<<"Read done\n";
state=1;
ReleaseMutex(hMutex);
PulseEvent(hReadDone);
}
}
}
void main()
{
HANDLE TName[2];
DWORD ThreadID;
state= 1;
hMutex= CreateMutex(NULL, FALSE, NULL);
hWriteDone= CreateEvent(NULL, TRUE, FALSE, NULL);
hReadDone= CreateEvent(NULL, TRUE, FALSE, NULL);
TName[0]= CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)Writer,
NULL, 0, &ThreadID);
TName[1]= CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)Reader,
NULL, 0, &ThreadID);
WaitForMultipleObjects(2, TName, TRUE, INFINITE);
CloseHandle(TName);
getchar();
}
You should never cast a function pointer. Remove the (LPTHREAD_START_ROUTINE) casts from your code, fix the compiler errors, and try again. Never use casts to quell compiler errors.
The lpStartAddress
parameter of CreateThread
is of type LPTHREAD_START_ROUTINE
. Which is a function pointer compatible with this signature:
DWORD WINAPI ThreadProc(LPVOID lpParameter);
So you need to supply what the function expects. Your function Reader
does not fit the bill. Change its signature to be like this:
DWORD WINAPI Reader(LPVOID lpParameter)
{
....
}
And likewise for Writer
.
Every time you cast something to suppress a compiler warning you are trading an easy to diagnose compile time error for a hard to diagnose run time error. That's a very bad trade. So, as a general rule, don't use casts. Sometimes you'll need to break that rule, but do so in full understanding of what you are doing.
Your main
function also has a somewhat bogus signature. If you don't want to process arguments, then you should declare it like this:
int main()
Since you ignore the thread ID, you may as well pass NULL
for the final parameter of CreateThread
.
This also is wrong:
CloseHandle(TName);
The parameter of CloseHandle
is of type HANDLE
. You are passing a pointer to an array. You need to do this:
CloseHandle(TName[0]);
CloseHandle(TName[1]);
The Writer
function does not return a value. The compiler warns you about that, if you enable sufficient warnings. You should certainly do so.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.