1

我正在阅读一些互斥量和信号量。

我有一段代码

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

i 在外部某处被声明为全局变量。如果我创建计数为 3 的计数信号量,它不会有竞争条件吗?这是否意味着在这种情况下我应该使用二进制信号量或互斥量?

有人可以给我一些可以使用互斥锁、临界区和信号量的实用场景吗?

可能我读了很多。最后,我现在有点困惑。有人能理清思路吗。

PS:我知道互斥量和二进制信号量之间的主要区别是所有权。和计数信号量应该用作信令机制。

4

2 回答 2

7

互斥量和信号量之间的区别(我从未使用过 CriticalSection):

  • 使用条件变量时,它的锁必须是互斥锁。
  • 当使用超过 1 个可用资源时,您必须使用用可用资源数量初始化的信号量,因此当您的资源不足时,下一个线程会阻塞。
  • 当使用 1 个资源或某些只能由 1 个线程执行的代码时,您可以选择使用互斥锁或用 1 初始化的信号量(这是 OP 问题的情况)。
  • 当让一个线程等待另一个线程发出信号时,您需要一个用 0 初始化的信号量(等待线程执行 sem.p(),信号线程执行 sem.v())。
于 2012-09-07T14:52:24.077 回答
0

临界区对象是这里最简单的方法。它是一个轻量级的同步对象。

这是一些代码作为示例:

#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
}

链接:CreateThread 函数WaitForMultipleObjects 函数

随着线程:

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

互斥量和/或信号量为此目的而走得很远。

编辑:信号量基本上是一个可以多次释放的互斥锁。它存储了释放操作的数量,因此可以释放相同数量的等待。

于 2012-09-07T13:55:05.343 回答