二进制信号量和互斥量之间有区别吗?或者它们本质上是相同的?
当前回答
你可以通过以下方法清楚地记住不同之处:
互斥锁:用于保护关键区域, 互斥锁不能跨进程使用,只能在单个进程中使用 信号量:用于信号资源的可用性。 信号量既可以跨进程使用,也可以跨进程使用。
其他回答
厕所的例子是一个有趣的类比:
Mutex: Is a key to a toilet. One person can have the key - occupy the toilet - at the time. When finished, the person gives (frees) the key to the next person in the queue. Officially: "Mutexes are typically used to serialise access to a section of re-entrant code that cannot be executed concurrently by more than one thread. A mutex object only allows one thread into a controlled section, forcing other threads which attempt to gain access to that section to wait until the first thread has exited from that section." Ref: Symbian Developer Library (A mutex is really a semaphore with value 1.) Semaphore: Is the number of free identical toilet keys. Example, say we have four toilets with identical locks and keys. The semaphore count - the count of keys - is set to 4 at beginning (all four toilets are free), then the count value is decremented as people are coming in. If all toilets are full, ie. there are no free keys left, the semaphore count is 0. Now, when eq. one person leaves the toilet, semaphore is increased to 1 (one free key), and given to the next person in the queue. Officially: "A semaphore restricts the number of simultaneous users of a shared resource up to a maximum number. Threads can request access to the resource (decrementing the semaphore), and can signal that they have finished using the resource (incrementing the semaphore)." Ref: Symbian Developer Library
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!,
使用“互斥”就不会发生这种情况。没有其他线程可以解锁锁 在你的帖子里 使用“二进制信号量”可以实现这种情况。任何其他线程都可以解锁 线程中的锁
因此,如果您非常注重使用二进制信号量而不是互斥量,那么在锁定和解锁的“作用域”时应该非常小心。我的意思是,每个触及每个锁的控制流都应该触及一个解锁调用,也不应该有任何“第一次解锁”,而应该总是“第一次锁定”。
它们不是一回事。它们有不同的用途! 虽然这两种类型的信号量都有一个满/空状态,并且使用相同的API,但它们的用法非常不同。
互斥信号量 互斥信号量用于保护共享资源(数据结构、文件等)。
互斥信号量由接收它的任务“拥有”。如果Task B尝试semGive一个当前由Task a持有的互斥锁,Task B的调用将返回一个错误并失败。
互斥对象总是使用以下顺序:
- SemTake - Critical Section - SemGive
这里有一个简单的例子:
Thread A Thread B Take Mutex access data ... Take Mutex <== Will block ... Give Mutex access data <== Unblocks ... Give Mutex
二进制信号量 二进制信号量解决了一个完全不同的问题:
任务B被挂起等待某些事情发生(例如传感器被绊倒)。 传感器跳闸和中断服务程序运行。它需要通知任务的行程。 任务B应运行并对传感器跳闸采取适当的操作。然后继续等待。
Task A Task B
... Take BinSemaphore <== wait for something
Do Something Noteworthy
Give BinSemaphore do something <== unblocks
注意,对于二进制信号量,B获取信号量,a给出信号量是可以的。 同样,二进制信号量不能保护资源不被访问。信号量的给予和获取从根本上是分离的。 对于同一个任务来说,对同一个二进制信号量的给予和获取通常没有什么意义。
在窗口,差异如下所示。 MUTEX:成功执行等待的进程必须执行一个信号,反之亦然。二进制信号量:不同的进程可以在一个信号量上执行等待或信号操作。
答案可能取决于目标操作系统。例如,我所熟悉的至少一个RTOS实现允许对单个OS互斥量进行多个连续的“get”操作,只要它们都来自同一个线程上下文中。在允许另一个线程获得互斥量之前,多个get必须被相等数量的put替换。这与二进制信号量不同,对于二进制信号量,无论线程上下文如何,一次只允许一个get。
这种互斥锁背后的思想是,通过一次只允许一个上下文修改数据来保护对象。即使线程获得了互斥量,然后调用进一步修改对象的函数(并在自己的操作周围获得/放置保护互斥量),这些操作仍然应该是安全的,因为它们都发生在单个线程下。
{
mutexGet(); // Other threads can no longer get the mutex.
// Make changes to the protected object.
// ...
objectModify(); // Also gets/puts the mutex. Only allowed from this thread context.
// Make more changes to the protected object.
// ...
mutexPut(); // Finally allows other threads to get the mutex.
}
当然,在使用此特性时,必须确保单个线程中的所有访问都是安全的!
我不确定这种方法有多普遍,或者它是否适用于我所熟悉的系统之外。有关这种互斥锁的示例,请参阅ThreadX RTOS。
推荐文章
- 为什么pthreads的条件变量函数需要互斥?
- 并发HashSet<T>在。net框架?
- Trap和中断的区别是什么?
- 互斥实例/教程?
- 为什么Linux被称为单片内核?
- 如何检查Python的操作系统?
- 在Swift中,什么相当于Objective-C的“@synchronized”?
- 信号量和监视器——有什么不同?
- 如何使用JavaScript找到操作系统的详细信息?
- 我如何检查操作系统与预处理器指令?
- 如何在没有操作系统的情况下运行程序?
- 线程之间共享哪些资源?
- Windows、Mac OS X和Linux是用什么语言编写的?
- 什么时候应该使用自旋锁而不是互斥锁?
- context . start前台服务()没有调用service . start前台()