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


当前回答

You obviously use mutex to lock a data in one thread getting accessed by another thread at the same time. Assume that you have just called lock() and in the process of accessing data. This means that you don’t expect any other thread (or another instance of the same thread-code) to access the same data locked by the same mutex. That is, if it is the same thread-code getting executed on a different thread instance, hits the lock, then the lock() should block the control flow there. This applies to a thread that uses a different thread-code, which is also accessing the same data and which is also locked by the same mutex. In this case, you are still in the process of accessing the data and you may take, say, another 15 secs to reach the mutex unlock (so that the other thread that is getting blocked in mutex lock would unblock and would allow the control to access the data). Do you at any cost allow yet another thread to just unlock the same mutex, and in turn, allow the thread that is already waiting (blocking) in the mutex lock to unblock and access the data? Hope you got what I am saying here? As per, agreed upon universal definition!,

使用“互斥”就不会发生这种情况。没有其他线程可以解锁锁 在你的帖子里 使用“二进制信号量”可以实现这种情况。任何其他线程都可以解锁 线程中的锁

因此,如果您非常注重使用二进制信号量而不是互斥量,那么在锁定和解锁的“作用域”时应该非常小心。我的意思是,每个触及每个锁的控制流都应该触及一个解锁调用,也不应该有任何“第一次解锁”,而应该总是“第一次锁定”。

其他回答

二进制信号量和互斥量的区别: 所有权: 信号量甚至可以从非当前所有者发出信号(发布)。这意味着您可以简单地从任何其他线程发布,尽管您不是所有者。

信号量是进程中的公共属性,它可以简单地由非所有者线程发布。 请用粗体字标出这个区别,这意味着很多。

除了互斥对象有一个所有者之外,这两个对象还可以针对不同的用途进行优化。互斥锁被设计为只保留很短的时间;违反这一点会导致糟糕的性能和不公平的调度。例如,一个正在运行的线程可能被允许获取一个互斥量,即使另一个线程已经被阻塞在这个线程上。信号量可以提供更多的公平性,或者可以使用几个条件变量强制实现公平性。

You obviously use mutex to lock a data in one thread getting accessed by another thread at the same time. Assume that you have just called lock() and in the process of accessing data. This means that you don’t expect any other thread (or another instance of the same thread-code) to access the same data locked by the same mutex. That is, if it is the same thread-code getting executed on a different thread instance, hits the lock, then the lock() should block the control flow there. This applies to a thread that uses a different thread-code, which is also accessing the same data and which is also locked by the same mutex. In this case, you are still in the process of accessing the data and you may take, say, another 15 secs to reach the mutex unlock (so that the other thread that is getting blocked in mutex lock would unblock and would allow the control to access the data). Do you at any cost allow yet another thread to just unlock the same mutex, and in turn, allow the thread that is already waiting (blocking) in the mutex lock to unblock and access the data? Hope you got what I am saying here? As per, agreed upon universal definition!,

使用“互斥”就不会发生这种情况。没有其他线程可以解锁锁 在你的帖子里 使用“二进制信号量”可以实现这种情况。任何其他线程都可以解锁 线程中的锁

因此,如果您非常注重使用二进制信号量而不是互斥量,那么在锁定和解锁的“作用域”时应该非常小心。我的意思是,每个触及每个锁的控制流都应该触及一个解锁调用,也不应该有任何“第一次解锁”,而应该总是“第一次锁定”。

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

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

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

例如,你可以在互斥锁中启用错误检查属性。错误检查互斥量返回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");

The basic issue is concurrency. There is more than one flow of control. Think about two processes using a shared memory. Now only one process can access the shared memory at a time. If more than one process accesses the shared memory at a time, the contents of shared memory would get corrupted. It is like a railroad track. Only one train can run on it, else there would be an accident.So there is a signalling mechanism, which a driver checks. If the signal is green, the train can go and if it is red it has to wait to use the track. Similarly in case of shared memory, there is a binary semaphore. If the semaphore is 1, a process acquires it (makes it 0) and goes ahead and accesses it. If the semaphore is 0, the process waits. The functionality the binary semaphore has to provide is mutual exclusion (or mutex, in short) so that only one of the many concurrent entities (process or thread) mutually excludes others. It is a plus that we have counting semaphores, which help in synchronizing multiple instances of a resource.

互斥是信号量提供的基本功能。现在在线程上下文中,我们可能有不同的名称和语法。但基本概念是相同的:如何在并发编程中保持代码和数据的完整性。在我看来,像所有权和相关检查这样的东西是由实现提供的改进。