【发布时间】:2016-06-30 06:01:03
【问题描述】:
我注意到,在大多数条件变量示例中,我看到的内容如下:
pthread_cond_signal(&cond, &lock);
pthread_mutex_unlock(&lock);
我的问题是为什么要按这个顺序完成。为什么在释放锁之前先广播信号?如果在信号广播和解锁之间发生上下文切换,其他线程将从睡眠中唤醒并尝试访问有问题的锁,看到它仍然被锁定,然后回到待机状态,所以信号不会浪费了?
为什么这不是更好的解决方案:
pthread_mutex_unlock(&lock);
pthread_cond_signal(&cond, &lock);
在这种情况下,锁在休眠的线程被唤醒之前被释放,因此它们实际上可以访问之前锁定的数据。
谁能帮我解决这个问题?
【问题讨论】:
-
@PaulGriffiths 该线程中与我的问题有关的答案指出“但这可能导致线程的最佳调度”,但没有详细说明原因。
-
icecrime 的答案链接到来自 David Butenhof 的电子邮件(诚然,此类信息在答案本身中会更好),其中详细说明了原因(以及有关为什么添加该警告性语言的一些历史细节符合标准)。结果是,除非您正在处理实时性能,否则在不锁定互斥锁的情况下发出信号或广播并没有太大问题。
-
接受this question 的答案也可能会有所帮助。某些实现可能有一个互斥体等待队列,以避免您描述的那种多余的唤醒。
-
如果你有一个糟糕的实现,会不必要地唤醒线程,那就使用更好的实现。体面的人应该知道,等待条件变量的线程在释放关联的互斥锁之前还没有准备好运行。如果实现无论如何都会唤醒线程,那么大概是有原因的。
-
另外,您认为更好的解决方案显然更糟,因为它有两个昂贵的操作而不是一个。在持有关联互斥体的同时向条件变量发出信号基本上是免费的——它除了本地状态之外不会影响其他任何东西。但是,在释放锁时向条件变量发出信号需要同步,并且可能唤醒其他线程。
标签: c multithreading