Semaphore Vs Mutex

2019-05-31 04:50发布

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.

3条回答
淡お忘
2楼-- · 2019-05-31 05:14

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.

查看更多
Animai°情兽
3楼-- · 2019-05-31 05:20

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()).
查看更多
太酷不给撩
4楼-- · 2019-05-31 05:35

If your critical section is really just about incrementing i and you are on x86 architecture under Windows, you can use

_InterlockedIncrement((LONG *)&i);

to atomically increment it (it's an intrinsic that map a CPU instruction, no a real function call). Other compile systems (like GCC) have their own way of calling this intrinsic.

查看更多
登录 后发表回答