1

I was reading a bit of Mutex and semaphore.

I have piece of code

int func()
{
 i++;
 return i;
}

i is declared somewhere outside as a global variable. If i create counting semaphore with count as 3 won't it have a race condition? does that mean i should be using a binary semaphore or a Mutex in this case ?

Can somebody give me some practical senarios where Mutex, critical section and semaphores can be used.

probably i read lot. At the end i am a bit confused now. Can somebody clear the thought.

P.S: I have understood that primary diff between mutex and binary semaphore is the ownership. and counting semaphore should be used as a Signaling mechanism.

jc tronics
  • 97
  • 1
  • 1
  • 5
  • You're right, in this case a mutex is the right choice. But, as is, the question is too broad for SO imo. – Luchian Grigore Sep 07 '12 at 13:31
  • Can you explain more about how different threads will access `i`? – japreiss Sep 07 '12 at 13:34
  • Suppose i m creating 100 threads thru a for loop. And individual thread calls this function. But i have created a semaphore of count 5. Then i still need a Mutually exclusive lock for accessing the shared resource rit ? – jc tronics Sep 07 '12 at 13:46

2 Answers2

7

Differences between mutex and semaphore (I never worked with CriticalSection):

  • When using condition variables, its lock must be a mutex.
  • When using more than 1 available resources, you must use a semaphore initialized with the number of available resources, so when you're out of resources, the next thread blocks.
  • When using 1 resource or some code that may only be executed by 1 thread, you have the choice of using a mutex or a semaphore initialized with 1 (this is the case for OP's question).
  • When letting a thread wait until signaled by another thread, you need a semaphore intialized with 0 (waiting thread does sem.p(), signalling thread does sem.v()).
stefaanv
  • 14,072
  • 2
  • 31
  • 53
0

A critical section object is the easiest way here. It is a lightweight synchronisation object.

Here is some code as example:

#define NUMBER_OF_THREADS 100

// global
CRITICAL_SECTION csMyCriticalSectionObject;
int i = 0;
HANDLE hThread[NUMBER_OF_THREADS];



int main(int argc, char *argv[]) 
{
  // initialize the critical section object
  InitializeCriticalSection(&csMyCriticalSectionObject);
  // create 100 threads:
  for (int n = 0; n < NUMBER_OF_THREADS; n++)
  {
    if (!CreateThread(NULL,0,func,hThread[n],0,NULL)) 
    {
      fprintf(stderr,"Failed to create thread\n");
    } 
  }
  // wait for all 100 threads:
 WaitForMultipleObjects(NUMBER_OF_THREADS,hThread,TRUE,INFINITE);
 // this can be made more detailed/complex to find each thread ending with its
 // exit code. See documentation for that
}

Links: CreateThread function and WaitForMultipleObjects function

With the thread:

// i is global, no need for i to returned by the thread
DWORD WINAPI func( LPVOID lpvParam ) 
{
  EnterCriticalSection(&csMyCriticalSectionObject);
  i++;
  LeaveCriticalSection(&csMyCriticalSectionObject);
  return GetLastError();
}

Mutex and/or semaphore are going to far for this purpose.

Edit: A semaphore is basically a mutex which can be released multiple times. It stores the number of release operations and can therefore release the same number of waits on it.

Arno
  • 4,994
  • 3
  • 39
  • 63
  • i know critical section is the best. But my doubts are between semaphore and mutex! – jc tronics Sep 07 '12 at 14:10
  • 1
    Well, then you may have a different scenario. I can't see why a semaphore is of any meaningful help for the described question. Answer edited. – Arno Sep 07 '12 at 14:25