在linux内核中,信号量用于为关键的数据部分提供互斥,而完成变量用于在等待事件的2个线程之间进行同步。为什么不使用信号量进行这种同步?在信号量上使用完成变量有什么好处吗?
答案 0 :(得分:12)
解释为何最初实施完成: http://lkml.indiana.edu/hypermail/linux/kernel/0107.3/0674.html
基本总结是我们有这个 (相当普遍)等待的方式 锁定某些事件 服务员堆栈上的信号量, 然后让服务员做一个 “down()”导致它阻止 直到它等待的东西 “up()”。
这个效果相当不错,但是它有一个 真的很小(而且不太可能)比赛 在SMP上,这不是一场比赛 这个想法本身,作为 信号量的实现。我们 可以修复信号量,但是 有几个原因没有:
- 信号量针对非争用情况进行了优化(故意)。 “等待完成”使用了 相反的默认情况
- 信号量非常复杂,特定于体系结构,完全是
由于这种优化。尝试去 改变他们是痛苦的。相反,我引入了概念 “等待完成”:
有关完成与信号量的最新帖子 http://lkml.org/lkml/2008/4/11/323
答案 1 :(得分:9)
您可能希望使用完成而不是信号量有两个原因。首先,多个线程可以等待完成,并且可以通过一次调用complete_all()
来释放它们。让信号量唤醒未知数量的线程会更复杂。
其次,如果等待线程要取消分配同步对象,则在使用信号量时存在竞争条件。也就是说,在使用up()
唤醒线程之前,服务员可能会被唤醒并释放对象。完成时不存在此种族。 (见Lasse的帖子。)