【发布时间】:2017-03-11 09:43:36
【问题描述】:
在Semaphore vs. Monitors - what's the difference?,
释放信号量的线程不必与释放信号量的线程相同 得到它。
如果线程没有获取信号量,那么线程如何释放信号量?
这里的信号量是指用忙等待实现的信号量,还是用进程阻塞实现的信号量?
谢谢。
【问题讨论】:
在Semaphore vs. Monitors - what's the difference?,
释放信号量的线程不必与释放信号量的线程相同 得到它。
如果线程没有获取信号量,那么线程如何释放信号量?
这里的信号量是指用忙等待实现的信号量,还是用进程阻塞实现的信号量?
谢谢。
【问题讨论】:
信号量涵盖与互斥锁不同的用例。
有了互斥体,你就对了。互斥锁通常用于防止代码中关键部分的并发执行。特定线程将在临界区开始时获取互斥锁,并在再次离开临界区时释放它。让一个互斥锁被另一个线程释放而不是获得它的线程意味着临界区跨越多个线程,这很可能不是您想要的方式。
信号量的用例略有不同。它表示资源的可用性。需要消耗资源的线程将获取信号量,这在概念上是获取底层资源。如果没有可用资源,acquire 将阻塞。
现在,在我们讨论一组固定资源(如一组可用的 I/O 端口)的场景中,获取线程再次释放资源是有意义的。我获取端口,做一些工作并在完成后释放它,以便其他线程可以处理它。
但这不是信号量的唯一用例。想想生产者/消费者:生产者线程可能提供资源(例如排队等待工作线程处理的项目),消费者线程将接受它们。在这些情况下,消耗的资源通常会消失,因此您不会在获取资源后释放资源。相反,生产线程调用 release 来指示有东西可供消费。消费者然后调用acquire来声明一个生产的资源并处理它。生产者永远不会调用acquire,消费者永远不会调用release。
【讨论】:
在许多情况下,获取信号量的线程无法释放它,因为它被阻塞等待某人释放信号量,并且它必须是其他线程释放(发信号)信号。
在忙着等待的情况下实现信号量绝对是可怕的。与锁不同,在某些情况下信号量会保持很长时间(秒或分钟,小时可能有点不寻常,但绝对有可能)。
显然,对信号量对象的引用需要存储在另一个线程可以访问它的地方。
【讨论】: