我已经成功实现了生产者线程和2个工作线程或消费者线程。
生产者线程使用pthread_cond_broadcast广播条件。并且pthread_cond_wait阻止了工作线程。
代码看起来像这样:
线程1(生产者线程):
pthread_mutex_lock
pthread_cond_broadcast
pthread_mutex_unlock
线程2(工人/消费者线程):
work = 1
while(1)
{
pthread_mutex_lock
while(!work)
{
work = 1;
pthread_cond_wait
}
// Thread operation
work = 0;
pthread_mutex_unlock
}
线程3(工人/消费者线程):
work = 1
while(1)
{
pthread_mutex_lock
while(!work)
{
work = 1;
pthread_cond_wait
}
// Thread operation
work = 0;
pthread_mutex_unlock
}
我的问题是,为什么线程2或线程3不会重新执行自身?
换句话说,当条件由线程1广播时,假设线程2首先对该条件解除阻塞,执行线程操作并调用thread_cond_wait并阻塞自身。
现在,线程3在该条件下解除阻塞,执行线程操作并调用thread_cond_wait并自身阻塞。
在这个时间点,两个线程都被阻塞以等待条件,条件变量是否被重置?如果是这样,它怎么知道何时重置,因为我可以拥有5个工作线程,而不是2个工作线程?
为什么在相同条件下线程2和线程3不会再次解除阻塞?
我想了解内部机制,即在发送新广播之前,线程如何针对特定条件仅一次(而不是再次)解除阻塞。
我尝试阅读有关此内容的信息,但是我所看到的只是,如果发送了条件广播,则所有等待该条件的线程都将被阻塞。我不明白的是为什么同一个线程在相同条件下不会多次解除阻塞?
我尝试查看pthread_cond_t,但是没有任何线索。
对于我所缺少或错误思考的任何帮助或建议,将不胜感激。
谢谢
答案 0 :(得分:2)
我的问题是为什么线程2或线程3不重新执行 本身?
因为那不是条件变量的工作方式。
换句话说,当条件由线程1广播时,让 说线程2首先解除条件的阻塞,执行线程 操作并调用thread_cond_wait并自行阻止。
现在线程3在该条件下解除阻塞,执行线程操作并 调用thread_cond_wait并阻止自身。
此时,两个线程都被阻塞,等待 条件,条件变量是否也要重置?
该问题表明条件变量表示的状态模型很差,因为答案是肯定和否定。实现细节可能相差很大,但是从概念上讲,由CV管理的主要状态由当前在CV上等待的线程的“等待集”组成。这些线程无法继续,即在CV上被阻止。
在简历上可以执行三个主要操作:
CV不带有指示它们是否已被信号通知的持久状态。他们只知道他们的等待集和(在pthreads实现中)一个互斥体,从等待集中删除的线程必须先获取一个互斥体,然后它们才能从等待操作返回。无需重置CV就可以使其接受更多线程进入其等待集中。
如果是这样,怎么做 知道何时重置,因为我可以拥有5个线程而不是2个工作线程 工作线程?
它不会重置,在任何意义上都不会与已描述的操作有所不同。等待它的任何线程都将添加到等待集中,并且只要它保留在那里就没有资格进行调度。从根本上说,CV上的任何信号和广播操作都会影响该操作的等待时间。从等待集中删除的线程不再在CV上被阻止,而是在获取相关的互斥锁时可能被阻止。
为什么线程2和线程3不会再次解除自身阻塞 同样的条件?
因为那不是条件变量的工作方式。
线程2和3再次等待是CV支持的唯一一种重置。这些线程已被读取到等待集中,没有理由认为它们将在对该CV执行(另一个)信号或广播操作之前继续执行。没有过去的信号/广播的存储,只有等待集的当前内容。