我读到了信号量和互斥量之间的区别之一是在互斥锁的情况下,进程/线程(曾经拥有锁)只能释放锁。但是在信号量的情况下,任何其他进程都可以释放信号量。当一个没有信号量的进程可以释放信号量时,我就会产生怀疑。拥有信号量有什么用?
假设我有两个进程A和B.假设进程A有一个信号量并执行一些关键任务。现在让我们说进程B发送信号以释放信号量。在这种情况下,即使正在执行某项关键任务,进程A是否会释放信号量?
答案 0 :(得分:0)
你正在做出一半的感觉。这与所有权无关。信号量(和互斥体)中的合作伙伴发布可用,例如,在我最喜欢的线程乒乓的面试问题中。事实上,我已经特意尝试合作 - 一次发布3个可用的互斥体(Linux / Solaris / AIX),并且合作伙伴版本确实按照预期为互斥体工作 - 即mutex成功发布并且线程阻止它恢复执行。但是,这当然是Posix禁止的。
答案 1 :(得分:0)
我认为你可能会对信号量和互斥量之间的所有差异感到困惑。互斥锁提供互斥。信号量计数直到达到开始排除的水平。计数为1的信号量虽然会给互斥锁提供类似的语义。
一个很好的例子就是电视机。只有这么多人可以观看同一台电视机,所以用信号灯保护它是有道理的。任何人都可以停止看电视了。电视的遥控器一次只能由一个人操作,所以你可以用互斥锁保护它。
有些人在阅读......
答案 2 :(得分:0)
"假设我有两个进程A和B.假设进程A有一个信号量并执行一些关键任务。现在让我们说进程B发送信号以释放信号量。在这种情况下,即使正在执行某项关键任务,进程A是否会释放信号量?"
这里要注意的一个关键点是OS内核的作用。进程B无法向进程A发送信号以释放信号量'。它可以做的是请求内核授予它对资源的访问权限。进程A已请求内核,内核授予它对资源的访问权限。 现在,进程A完成其工作后,将让内核知道它已完成资源,然后内核授予对B的访问权。
"当一个没有信号量的进程可以释放信号量时,我的疑问就出现了。拥有信号量有什么用?"
互斥锁和信号量之间的主要区别在于,信号量序列化对多个资源实例的访问。当有一个资源实例时,Mutex会做同样的事情。
在信号量的情况下由内核维护计数,而互斥是计数为1的特殊情况。
考虑客户在银行排队等候的流程。 信号量的使用类似于为客户提供多个柜员的情况。互斥的使用类似于只有一个出纳员的情况。
假设有进程A,B和C需要并发访问资源(锁,文件或内存中的数据结构等)。进一步假设有2个资源实例。因此,一次最多可以授予两个进程访问权限。
进程A请求按照所需语义访问资源实例。这个对内核的请求涉及数据结构以识别资源和最大实例数2.内核创建计数为2的信号量,授予对资源的访问权限并将计数减少到1,因为现在只有一个其他进程可以获得访问权。
现在,进程B通过遵循相同的语义来请求对资源的访问。内核授予它访问权限并将计数减少到0。
现在进程C请求访问,但内核使其处于等待状态,因为count为0且不超过2个进程可以获得并发访问。
进程A完成资源并让内核知道。内核注意到这一点,并授予对一直等待的进程C的访问权。
对于互斥锁,内核一次只允许一个进程访问资源。
答案 3 :(得分:0)
普通的二进制信号量基本上用于同步。但是,互斥锁用于独占访问资源。互斥体是信号量的一种特殊变体,它一次只允许一个锁定器,并且所有权比正常信号量更严格,例如互斥锁应该只由获取它的线程释放。此外,请注意,如果是pthread,快速互斥锁可能无法检查与所有权相关的此错误,而错误检查互斥锁应返回错误。
对于与2进程A和B相关的查询,进程A应通过内核与其关键工作完成,以便资源可用于等待进程,如B。
您也可以在此链接中找到一些相关信息: When should we use mutex and when should we use semaphore
答案 4 :(得分:-1)
没有"有"一个信号量。信号量不像互斥体那样拥有所有权。您描述的代码很简单。如果您的代码有问题,互斥锁也不会起作用。
考虑信号量最典型的例子 - 在一段轨道上一次允许一列火车。如果列车是一个线程,您可以使用互斥锁实现此功能。火车将在上轨道之前锁定轨道互斥锁,并在离开轨道后将其解锁。
但是如果列车本身是多线程的呢?哪个帖子应该拥有该曲目?
如果信号设备是线程,而不是火车呢?这里,检测进入轨道的列车的信号装置必须锁定轨道,而检测离开轨道的列车的信号装置必须将其解锁。
互斥锁适用于特定线程在短时间内拥有某些内容的情况。该线程可以拥有"互斥体。信号量对于没有线程拥有线程拥有任何东西或什么都没有的情况很有用。