2012-09-07 190 views
1

我正在读一点互斥量和信号量。信号量与互斥量

我有一段代码

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

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

有人可以给我一些可以使用互斥量,临界截面和信号量的实际参数。

可能我读了很多。最后,我现在有点困惑。有人能清楚这个想法吗?

P.S:我已经理解互斥体和二进制信号量之间的主要差异是所有权。并且计数信号量应该用作信令机制。

+0

你说得对,在这种情况下,互斥是正确的选择。但是,现在这个问题太广泛了。 –

+0

你能解释更多关于不同的线程如何访问'i'吗? – japreiss

+0

假设我通过for循环创建100个线程。个别线程调用这个函数。但是我创建了一个count为5的信号量。那么我仍然需要一个互斥锁来访问共享资源rit? –

回答

0

A critical section object是最简单的方法。它是一个轻量级的同步对象。

下面是一些代码示例:

#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 functionWaitForMultipleObjects function

与螺纹:

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

互斥和/或信号量要远远为此, 。

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

+0

我知道关键部分是最好的。但我的疑惑是在信号和互斥体之间! –

+1

那么,你可能会有不同的情况。我不明白为什么信号量对于所描述的问题有任何有意义的帮助。回答编辑。 – Arno

7

互斥和信号灯的区别(我从来没有与CriticalSection的工作):

  • 当使用条件变量,它的锁必须是互斥。
  • 当使用多于1个可用资源时,您必须使用已用可用资源数初始化的信号量,因此当您资源不足时,下一个线程会阻塞。
  • 当使用1个资源或一些只能由1个线程执行的代码时,您可以选择使用1初始化的互斥量或信号量(OP的问题就是这种情况)。当让一个线程等待直到另一个线程发出信号时,你需要一个信号量为0(等待线程执行sem.p(),信号线程执行sem.v())。
0

如果你的关键部分是真的只是增加我和你是在Windows下的x86架构,您可以使用

_InterlockedIncrement((LONG *)&i); 

可以原子方式增加它(那就是图个CPU指令的内在,没有一个真正的函数调用)。其他编译系统(如GCC)有自己的方式来调用这个内在的。