信号量是一种编程概念,经常用于解决多线程问题。我对社区的问题是:

什么是信号量,如何使用它?


当前回答

互斥量只是一个布尔值,而信号量是一个计数器。

两者都用于锁定部分代码,这样就不会有太多线程访问它。

例子

lock.set()
a += 1
lock.unset()

现在,如果lock是一个互斥锁,这意味着无论有多少线程尝试访问受保护的代码片段,它将始终处于锁定或解锁状态(表面下是一个布尔值)。当被锁定时,任何其他线程都会等待它被前一个线程解锁/取消设置。

现在想象一下,如果lock在引擎盖下是一个具有预定义MAX值的计数器(在我们的例子中是2)。然后,如果有两个线程试图访问该资源,那么lock的值将增加到2。如果第三个线程试图访问它,它就会等待计数器低于2,以此类推。

如果lock作为一个信号量的最大值为1,那么它将完全作为一个互斥量。

其他回答

信号量是一个包含自然数(即大于或等于零的整数)的对象,在自然数上定义了两个修改操作。一个运算V,给自然数加1。另一个操作,P,将自然数减少1。这两个活动都是原子的(即没有其他操作可以与V或P同时执行)。

因为自然数0不能减少,所以在包含0的信号量上调用P将阻塞调用进程(/thread)的执行,直到该数字不再为0,P可以成功(原子地)执行为止。

正如在其他回答中提到的,信号量可用于将对某个资源的访问限制为最大(但可变的)进程数。

互斥量只是一个布尔值,而信号量是一个计数器。

两者都用于锁定部分代码,这样就不会有太多线程访问它。

例子

lock.set()
a += 1
lock.unset()

现在,如果lock是一个互斥锁,这意味着无论有多少线程尝试访问受保护的代码片段,它将始终处于锁定或解锁状态(表面下是一个布尔值)。当被锁定时,任何其他线程都会等待它被前一个线程解锁/取消设置。

现在想象一下,如果lock在引擎盖下是一个具有预定义MAX值的计数器(在我们的例子中是2)。然后,如果有两个线程试图访问该资源,那么lock的值将增加到2。如果第三个线程试图访问它,它就会等待计数器低于2,以此类推。

如果lock作为一个信号量的最大值为1,那么它将完全作为一个互斥量。

这是一个老问题,但信号量最有趣的用途之一是读/写锁,但没有明确提到。

r/w锁的工作方式很简单:为读取器消耗一个许可证,为写入器消耗所有许可证。 事实上,一个简单的r/w锁实现,但需要在读取时修改元数据(实际上是两次),这可能会成为瓶颈,但仍然比互斥锁或锁好得多。

另一个缺点是,写入也可以很容易地启动,除非信号量是公平的,或者写入在多个请求中获得许可,在这种情况下,它们之间需要一个显式的互斥。

进一步阅读:

信号量是一种锁定资源的方法,以保证在执行一段代码时,只有这段代码可以访问该资源。这可以防止两个线程并发访问一个资源,从而导致问题。

硬件或软件标志。在多任务系统中,信号量是一个变量,其值表示公共资源的状态。需要资源的进程检查信号量以确定资源状态,然后决定如何继续。