什么时候需要使用信号量?
我能想到的唯一例子就是限制同时访问相同数据/代码的线程数量...
还有其他情况下,信号量会是最好的解决方案吗?
什么时候需要使用信号量?
我能想到的唯一例子就是限制同时访问相同数据/代码的线程数量...
还有其他情况下,信号量会是最好的解决方案吗?
信号量可能适用于进程间的信号传递。但在多线程编程中,应避免使用信号量。如果需要对资源进行独占访问,请使用互斥锁。如果需要等待信号,请使用条件变量。
即使是最常见的资源池案例,也可以通过条件变量比信号量更简单、更安全地实现。让我们看看这种情况。使用信号量的天真实现将如下(伪代码):
wait for semaphore to open
take a resource out of the pool
use the resource
put it back to the pool
open the semaphore for one more thread
第一个问题是信号量并不能保护池免受多个线程的访问。因此,需要另一种保护措施。让它成为锁:
wait for semaphore to open
acquire the lock for the pool
take a resource out of the pool
release the lock
use the resource
acquire the lock
put the resource back to the pool
release the lock
open the semaphore for one more thread
acquire the lock
while the resource pool is empty,
wait for condition variable to be signaled
take a resource out of the pool
release the lock
use the resource
acquire the lock
put the resource back to the pool
release the lock
signal the condition variable
在这种情况下,添加非阻塞获取没有问题:
acquire the lock
if the resource pool is not empty,
take a resource out of the pool
release the lock
if the pool was empty, return
如您所见,它甚至不需要访问条件变量,并且对阻塞情况没有任何影响。对我来说,它明显优于使用信号量。
连接池。
即,您有20个连接和150个线程。在这种情况下,您将拥有一个信号量来控制对这20个连接的访问。
信号量可以被一个线程获取,也可以由另一个线程释放。而锁通常无法实现这一点。我在将资源的控制权从线程A传递给线程B时使用了这个功能。在这种特殊情况下,我必须控制顺序以避免死锁。