Word from the Author

"One mans mistake is another mans break"
Most of the article(s) which I have posted here are based on my own personal experience. Please do not get aggravated if you disagree with what I wrote.This is just my opinion and it might not be worth much. In case you find some errors or mistakes , have any other useful information which others including myself would benefit from or if you like an article you can always post your messages and comments here.

Thread Synchronization C++

I recently met a developer who was complaining about the lack of  material and articles available online regarding thread synchronization . According to him either the articles were too detailed or simply too vague.
I therefore decided to give my two cents on the topic , since I seem to have some extra time on my hands these days. This topic could be very advanced and I would more than appreciate and welcome other developers to comment on this topic and if you believe I am going wrong somewhere putting me write would be worth the 25 minutes it took me to write about this topic.

Threads are synchronized using the following methods:
Events,Mutex,Semaphores and Critical Sections

The following diagram shows what each method does and how its implemented

 








Example of Using a Triggering Event:

HANDLE HEvent;
void MyFunction(void *p)
{
Start:
WaitForSingleObject ( HEvent , INFINITE );      
cout << "\n Event Triggered" ;     
goto Start;
cout << "This Line would never be called \n";
return;
}

void main()
{
cout << "Main Thread Started";
HEvent = CreateEvent(NULL,false,false,"NAME"); 
_beginthread(MyFunction,0,0);
Sleep(3000);
SetEvent(HEvent); //Make Event Block
cin.get();
}       

Example of Using a Mutex:
HANDLE hMutex; 

void threadA(void* dummy)    //Thread A Procedure
{
WaitForSingleObject(hMutex, INFINITE);  //Check if handle is in use  released ?
for(int i = 0; i < 10; i++)              
cout << "testA" << endl;  //will block other wise it will continue
ReleaseMutex(hMutex);
}

void threadB(void* dummy)
{
WaitForSingleObject(hMutex, INFINITE);
for(int i = 0; i < 10; i++)
cout << "testB" << endl;
ReleaseMutex(hMutex);
}

void main()
{
hMutex = CreateMutex(NULL, false, "fileMutex");
_beginthread(threadA,0,NULL);
_beginthread(threadB,0,NULL);
}

Example of Using a Semaphore. 
I picked and modified this example from an online source , I cant seem to find the link to that site (Apologies to the original author) but I found a trace of that code in one of my projects.You don't really find good examples of semaphores online.
 
#define MAX_SEM_COUNT 10
#define THREADCOUNT 12 //No of threads to be created

HANDLE ghSemaphore;

DWORD WINAPI ThreadProc( LPVOID );

void main()
{
  HANDLE aThread[THREADCOUNT];
  DWORD ThreadID;
  int i;

  // Create a semaphore with initial and max counts of MAX_SEM_COUNT
  ghSemaphore = CreateSemaphore(NULL,MAX_SEM_COUNT,MAX_SEM_COUNT,NULL);     

  // Create worker threads
  for( i=0; i < THREADCOUNT; i++ )
  {
    aThread[i] = CreateThread(NULL,0,ThreadProc,NULL,0,&ThreadID);
  }

  // Wait for all threads to terminate
  WaitForMultipleObjects(THREADCOUNT, aThread, TRUE, INFINITE);

  // Close thread and semaphore handles
  for( i=0; i < THREADCOUNT; i++ )
    CloseHandle(aThread[i]);
    CloseHandle(ghSemaphore);
}


DWORD WINAPI ThreadProc( LPVOID lpParam )
{
  DWORD dwWaitResult;
  BOOL bContinue=TRUE;

  while(bContinue)
  {
    // Try to enter the semaphore gate.
    dwWaitResult = WaitForSingleObject(ghSemaphore,INFINITE); // zero-second time-out interval

    switch (dwWaitResult)
    {
      // The semaphore object was signaled.
      case WAIT_OBJECT_0:
        // TODO: Perform task
        printf("Thread %d: wait succeeded\n", GetCurrentThreadId());
        bContinue=FALSE;

        // Simulate thread spending time on task
        Sleep(5);

        // Release the semaphore when task is finished

        if (!ReleaseSemaphore(ghSemaphore,1,NULL) )
        {
          printf("ReleaseSemaphore error: %d\n", GetLastError());
        }
        break;

      // The semaphore was nonsignaled, so a time-out occurred.
      case WAIT_TIMEOUT:
        printf("Thread %d: wait timed out\n", GetCurrentThreadId());
        break;
    }
  }
  return TRUE;
 

No comments:

Post a Comment