假设广播线程在只有 3 个线程在等待时pthread_cond_wait
进行广播,并且在广播线程完成广播后的第 4 个线程调用,第 4 个线程是否会退出等待状态。以及如何重置条件变量,以便广播线程有时可以稍后重新广播给等待线程。
2 回答
第 4 个线程会脱离等待状态吗
不,直到有另一个广播或信号。
以及如何重置条件变量,以便广播线程有时可以稍后重新广播给等待线程。
最简单的想象是,条件变量所做的一切都是在与条件变量关联的互斥锁下同步的。所以在你广播的时候,所有等待的东西(不知何故)都进入了一个试图唤醒并获取互斥锁的状态。然后,广播线程释放互斥锁。因此,当您广播时,真正“重置”的不是条件变量,而是前三个线程从等待条件变量转移到等待互斥体。
为了等待 condvar,您的第 4 个线程必须首先获取互斥锁。这可能发生在前三个线程设法唤醒并获取互斥体之前或之后,但它显然发生在广播之后,因此您的第 4 个线程不是处于“尝试唤醒”状态,而是处于“等待信号”或广播”状态。
实际上它比这更复杂——您实际上不必为了广播条件变量而持有互斥锁。所以条件变量必须包括一些额外的内部同步(我不知道 linux 的具体细节),以确保所有在广播之前等待的线程都将它们的状态作为单个操作更改。
但是,通常您最好持有互斥锁进行广播,因为您刚刚更改了服务员希望看到的内容时进行广播,并且从许多线程中查看的任何内容都是使用互斥锁同步的。你可以通过始终这样做来避免一些尴尬的情况。
第 4 个线程会退出等待状态吗?
不,除非条件变量在线程 4 等待时发出信号。
手册页解释:
该调用会解除对指定条件变量当前阻塞的
pthread_cond_broadcast()
所有线程的阻塞。cond
如果当前没有阻塞在 上的线程,则
pthread_cond_signal()
andpthread_cond_broadcast()
函数无效cond
。