I found code online that displays how to use threads from a tutorial by redKyle. In the ‘Race Condition’ tutorial, he basically shows how two threads are sent to a function. The objective of the function is to print ‘.’ and ‘#’ in sequence one hundred times each. He provides the code to get this to work, he does NOT provide the code for the mutex. I have modified the code to include the mutex so that to prevent one thread from accessing the variable that holds the last character printed while another thread is accessing it.
I got the code to work. Great! However, I kept changing the sleep value between 1 and 50. The mutex code works fine. However, when i set sleep to 0 (or just comment it out) the mutex no longer works and the values are no longer printed in the correct manner (I no longer see 200 characters of strictly alternating ‘#’ and ‘.’).
The following is the code:
#include "stdafx.h"
#include <iostream>
#include <windows.h>
using namespace std;
static char lastChar='#';
//define a mutex
HANDLE mutexHandle = NULL;
//flag to specify if thread has begun
bool threadStarted = false;
void threadProc(int *sleepVal, int *threadID)
{
cout<<"sleepVal: "<<*sleepVal<<endl;
for (int i=0; i<100; i++)
{
char currentChar;
threadStarted = true;
while(!threadStarted){}
//lock mutex
WaitForSingleObject(mutexHandle, INFINITE);
if (lastChar == '#')
currentChar = '.';
else
currentChar = '#';
Sleep(*sleepVal);
lastChar = currentChar;
ReleaseMutex(mutexHandle);
threadStarted = false;
// cout<<"\nSleepVal: "<<*sleepVal<<" at: "<<currentChar;
cout<<currentChar;
}//end for
}//end threadProc
int main()
{
cout<<"Race conditions by redKlyde \n";
int sleepVal1 = 50;
int sleepVal2 = 30;
//create mutex
mutexHandle = CreateMutex(NULL, false, NULL);
//create thread1
HANDLE threadHandle;
threadHandle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) threadProc, &sleepVal1, 0, NULL);
//create thread2
HANDLE threadHandle2;
threadHandle2 = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) threadProc, &sleepVal2, 0, NULL);
WaitForSingleObject(threadHandle, INFINITE);
WaitForSingleObject(threadHandle2, INFINITE);
cout<<endl<<endl;
CloseHandle(mutexHandle);
system("pause");
return 0;
}
So my question is: why does setting sleep to 0 void the mutex code.
Take notice that your print statement is not protected by the mutex, so one thread is free to print while the other is free to modify. By not sleeping, you’re allowing the scheduler to determine the print order based upon the quantum of the thread.
There are some things wrong:
1) You should not be sleeping inside a held lock. This is almost never correct.
2) Any place your data is shared, you should be guarding with a lock. This means that the print statement should be in the lock, too.