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