二进制信号量和互斥量之间有区别吗?或者它们本质上是相同的?


当前回答

虽然二进制信号量可以用作互斥量,但互斥量是一个更具体的用例,因为只有锁定了互斥量的进程才应该解锁它。这种所有权限制使我们有可能对以下情况提供保护:

意外释放 递归死锁 任务死亡死锁

这些限制并不总是存在,因为它们降低了速度。在代码开发期间,您可以暂时启用这些检查。

例如,你可以在互斥锁中启用错误检查属性。错误检查互斥量返回EDEADLK,如果你试图锁定同一个互斥量两次,如果你解锁了一个不是你的互斥量,返回EPERM。

pthread_mutex_t mutex;
pthread_mutexattr_t attr;
pthread_mutexattr_init (&attr);
pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_ERRORCHECK_NP);
pthread_mutex_init (&mutex, &attr);

一旦初始化,我们可以将这些检查放在我们的代码中,就像这样:

if(pthread_mutex_unlock(&mutex)==EPERM)
 printf("Unlock failed:Mutex not owned by this thread\n");

其他回答

互斥锁控制对单个共享资源的访问。它提供了获取()对资源的访问并在完成后释放()资源的操作。

信号量控制对共享资源池的访问。它提供Wait()操作,直到池中的一个资源可用,并提供Signal()操作,当它返回池时。

当一个信号量保护的资源数量大于1时,它被称为计数信号量。当它控制一个资源时,它被称为布尔信号量。布尔信号量相当于互斥量。

因此,信号量是比互斥量更高级别的抽象。互斥锁可以用信号量来实现,但不能用信号量来实现。

它们的同步语义非常不同:

互斥对象允许对给定资源的序列化访问,即多个线程等待一个锁,一次一个,正如前面所说,线程拥有锁,直到锁完成:只有这个特定的线程可以解锁它。 二进制信号量是一个值为0和1的计数器:任务阻塞在它上,直到任何任务执行sem_post。信号量宣布资源可用,并提供等待机制,直到发出可用信号。

因此,可以将互斥锁视为在任务之间传递的令牌,将信号量视为交通红灯(它向某人发出信号,表示可以继续进行)。

既然上面的答案都不能消除困惑,这里有一个答案可以消除我的困惑。

Strictly speaking, a mutex is a locking mechanism used to synchronize access to a resource. Only one task (can be a thread or process based on OS abstraction) can acquire the mutex. It means there will be ownership associated with mutex, and only the owner can release the lock (mutex). Semaphore is signaling mechanism (“I am done, you can carry on” kind of signal). For example, if you are listening songs (assume it as one task) on your mobile and at the same time your friend called you, an interrupt will be triggered upon which an interrupt service routine (ISR) will signal the call processing task to wakeup.

来源:http://www.geeksforgeeks.org/mutex-vs-semaphore/

正如这里许多人提到的,互斥锁用于保护关键代码段(又名临界段)。你将在同一个线程中获得互斥锁(lock),进入临界区,释放互斥锁(unlock)。

在使用信号量时,您可以让一个线程(例如线程a)等待一个信号量,直到另一个线程(例如线程B)完成任何任务,然后为线程a设置信号量以停止等待,并继续其任务。

你可以通过以下方法清楚地记住不同之处:

互斥锁:用于保护关键区域, 互斥锁不能跨进程使用,只能在单个进程中使用 信号量:用于信号资源的可用性。 信号量既可以跨进程使用,也可以跨进程使用。