pthreads互斥量与信号量
pthread库提供的信号量和互斥量有什么区别?
信号量有一个同步计数器,互斥量只是二进制(真/假)。
信号量经常被用作回答正在使用的资源的元素的确定机制 – 例如,表示n个工作线程的对象可能使用信号量来计算有多less工作线程可用。
事实是,你可以通过由互斥体同步的INT表示一个信号量。
我将要谈论互斥对二进制信号量。 您显然使用互斥锁来防止一个线程中的数据被另一个线程同时访问。
(假设你刚才调用了lock()并且正在访问一个数据,这意味着你不希望任何其他线程(或者同一个线程代码的另一个实例)访问被也就是说,如果在不同的线程实例上执行相同的线程代码,则命中该锁,那么lock()应该阻止控制stream。
这适用于使用不同线程代码的线程,该代码也访问相同的数据,并且也被相同的互斥锁locking。
在这种情况下,您仍在访问数据,您可能需要15秒才能到达互斥锁(这样互斥锁中被阻塞的另一个线程将会解锁并允许控制访问数据)。
你有没有允许另一个线程来解锁同一个互斥体,反过来又允许已经在互斥体锁中等待(阻塞)的线程解锁并访问数据? (希望你有我在这里说的。)
按照商定的普遍定义,
- 与“互斥体”这不可能发生。 没有其他线程可以解锁你的线程中的锁
- 与“二进制信号量”这可能会发生。 任何其他线程都可以解锁线程中的锁
所以,如果你非常需要使用二进制信号量而不是互斥量,那么你应该非常小心地“locking”locking和解锁,我的意思是说,每一个锁的每一个控制stream应该打一个解锁的电话,也不应该有任何“第一次解锁”,而应该始终是“第一次locking”。
互斥量用于避免多个线程之间的竞争状态。
而信号量用作跨多个进程使用的同步元素。
互斥体不能用二进制信号代替,因为一个进程等待信号而另一个进程释放信号量。 如果mutex的获取和释放都是由相同的处理。
这两篇文章解释了关于互斥和信号量的很好的细节。 这个堆栈溢出的答案告诉类似的答案。
semaphore
和mutex
量的区别在于机制和模式的区别。 不同之处在于他们的目的( 意图 )以及他们如何工作( 行为 )。
mutex
, barrier
, pipeline
是并行编程模式 。 Mutex
被用于( 意图 )保护critical section
并确保mutual exclusion
。 Barrier
使代理(线程/进程)不断地等待对方。
mutex
模式的一个特性( 行为 )是只有允许的代理(进程或线程)才能进入临界区,只有代理可以自动退出。
有时mutex
允许单个代理。 有些情况下,它允许多个代理(多个读者),并禁止一些其他代理(作家)。
semaphore
是一种可以用来( 打算 )实现不同模式的机制。 它( 行为 )通常是一个标志 (可能受互斥)的保护。 (一个有趣的事实是,甚至可以使用mutex
模式来实现信号量)。
在stream行文化中, semaphores
是内核提供的机制, mutexes
是由用户空间库提供的。
请注意,有关semaphores
和mutexes
semaphores
误解。 它表示semaphores
用于synchronization
。 mutexes
拥有ownership
。 这是由于stream行的OS书籍。 但事实是所有的互斥,信号量和屏障都用于同步 。 互斥体的意图不是ownership
而是mutual exclusion
。 这种误解给人气面试问题的兴起提出了mutexes
和binary-semaphores
的区别。
概要,
意图
- 互斥,互斥
- 信号量,实现并行devise模式
行为
- 互斥体,只有允许的代理进入关键部分,只有它(他们)可以退出
- 信号量,如果标志说进入,否则等到有人改变标志
从devise的angular度来看, mutex
更像是state-pattern
select的algorithm可以改变状态的状态模式。 binary-semaphore
更像strategy-pattern
, 外部algorithm可以改变状态,最终select运行的algorithm/策略。
信号量更多地用作标志,为此你不需要带上RTOS / OS。 信号量可能会被其他线程意外或故意地改变(比如由于错误的编码)。 当你线程使用互斥锁时,它拥有资源。 没有其他线程可以访问它,在资源获得免费之前。
厕所例子
互斥:
是厕所的关键。 一个人可以拥有钥匙 – 占用厕所 – 当时。 完成后,该人员将(释放)队列中下一个人的钥匙。
“互斥对象通常用来串行访问一段不能同时被多个线程执行的重入代码,一个互斥对象只允许一个线程进入受控段,强制其他线程试图访问该段等到第一个线程退出该部分。“
(互斥量实际上是一个值为1的信号量。)
信号:
是免费的相同的马桶钥匙的数字。 例如,假设我们有四个具有相同的锁和钥匙的厕所。 信号计数 – 密钥计数 – 在开始时设置为4(所有四个厕所都是免费的),然后计数值随着人进来而递减。如果所有的厕所都满了, 没有空闲密钥,信号计数为0.现在,当等式 一个人离开厕所,信号量增加到1(一个自由键),并给予队列中的下一个人。
“信号量限制共享资源的并发用户数达到最大数量,线程可以请求访问资源(递减信号量),并可以表示他们已经完成使用资源(增加信号量)。
资源
互斥锁只能应用于单个进程中的线程,不能像信号量一样在进程之间工作。