我在线程A中有以下代码,该代码使用pthread_cond_wait()进行阻止pthread_mutex_lock(&my_lock);if ( false == testCondition ) pthread_cond_wait(&my_wait,&my_lock);pthread_mutex_unlock(&my_lock);我在线程B中有以下代码,它向线程A发出信号pthread_mutex_lock(&my_lock);testCondition = true;pthread_cond_signal(&my_wait);pthread_mutex_unlock(&my_lock);如果没有其他线程,如果将pthread_cond_signal(&my_wait)移出关键部分块(如下所示),会有所不同吗?pthread_mutex_lock(&my_lock);testCondition = true;pthread_mutex_unlock(&my_lock);pthread_cond_signal(&my_wait); 最佳答案 我的建议通常是将pthread_cond_signal()调用保留在锁定区域内,但可能不是出于您的考虑。在大多数情况下,是否在保持锁定的情况下调用pthread_cond_signal()并不重要。 Ben是正确的,如果有另一个线程正在等待,某些调度程序可能会在释放锁定时强制执行上下文切换,因此您的线程可能会在调用pthread_cond_signal()之前被切换掉。另一方面,某些调度程序会在您调用pthread_cond_signal()时立即运行等待线程,因此,如果在持有锁的情况下调用它,等待线程将醒来,然后立即回到睡眠状态(因为现在已被阻塞)互斥体),直到信令线程将其解锁。确切的行为是高度特定于实现的,并且在不同的操作系统版本之间可能会发生变化,因此您不能依靠它。但是,所有这些看起来都超出了您的主要关注范围,即代码的可读性和正确性。通过这种微优化,您不太可能看到任何实际的性能收益(请记住优化的第一条规则:首先进行概要分析,然后进行优化)。但是,如果您知道等待线程的集合在设置条件和发送信号的点之间不能改变,那么考虑控制流就容易多了。否则,您必须考虑“如果线程A设置testCondition=TRUE并释放锁,然后线程B运行并看到testCondition为真,那么它将跳过pthread_cond_wait()并继续重置到testCondition,然后最终线程A运行并调用FALSE,这会唤醒线程C,因为线程B实际上并没有等待,但是pthread_cond_signal()不再适用。”这会造成混淆,并可能导致代码中难以诊断的竞争条件。因此,我认为最好发信号通知持有该锁。这样,您知道设置条件和发送信号相对于彼此是原子的。相关说明,您呼叫testCondition的方式不正确。在没有实际发出条件变量的情况下,pthread_cond_wait()可能会返回(尽管很少见),并且在其他情况下(例如,我上面描述的种族),即使条件为',信号也会最终唤醒线程。没错。为了安全起见,您需要将pthread_cond_wait()调用放在测试条件的pthread_cond_wait()循环中,以便在重新获取锁后如果不满足条件,则可以回叫到while()。在您的示例中,它看起来像这样:pthread_mutex_lock(&my_lock);while ( false == testCondition ) { pthread_cond_wait(&my_wait,&my_lock);}pthread_mutex_unlock(&my_lock);(我还纠正了您原始示例中的错字,即在pthread_cond_wait()调用中使用my_mutex而不是pthread_cond_wait()。)
10-07 16:44