我有一个读线程和多个写线程,如下所示。
读取线程:
pthread_mutex_lock(mutex);
while(1){
pthread_cond_wait(cond, mutex);
switch(state){
//do something
}
}
pthread_mutex_unlock(mutex);
写入线程1:
pthread_mutex_lock(mutex);
state = work;
pthread_cond_signal(cond);
//do something
pthread_mutex_unlock(mutex);
写入线程2:
pthread_mutex_lock(mutex);
state = lunch;
pthread_cond_signal(cond);
//do something
pthread_mutex_unlock(mutex);
假设state
是共享变量,并且读取线程在所有写入线程之前进入等待状态。
假设两个写线程试图同时获取mutex
,而write1获取mutex
并发送cond
。此时,write2和read线程都锁定在mutex
上,据我所知,没有哪个线程比mutex
有优先级,所以我们不能确定write1何时释放mutex
,read线程会获取它,这将导致信号丢失和重写状态。
我有两个问题:
- 我的理解是否正确,即上述情况是可能的
- 如果是,如何确保代码中没有遗漏信号
- 我的理解是否正确,即上述情况是可能的
是的,你是对的。
- 如果是,我如何确保代码中没有遗漏信号
如果您想确保变量CCD_;读取线程";,那么你必须确保没有";写入线程";改变变量CCD_ 9;读取线程";。例如,您可以将";读取线程";读取state
的值然后将该变量设置为一个特殊值;写入线程";CCD_ 11现在可以被新的值重写。
然而,这意味着;读取线程";必须等待";写入线程";,但是";写入线程";还必须等待";读取线程";。这是生产者和消费者的问题。一个典型的解决方案是有两个条件变量而不是一个:
- 一个用于";写入线程";以向";阅读器线程";新数据已准备好读取
- 一个用于";阅读器线程";以向";写入线程";现在可以写入新数据
为了最大限度地减少线程之间的等待,您可能希望允许多个数据集同时存储在程序中,例如通过实现队列。
因为您不想错过任何状态更改,所以写线程不应该覆盖变量,而应该将状态写入FIFO(例如,您可以将其实现为链表、管道或带有读/写指针的循环缓冲区(。然后,写线程将推送状态(FIFO中的每个状态一个新元素(,读线程将逐个弹出这些状态,直到FIFO为空(因为每次唤醒时FIFO中可能有多个状态(。
因此,您可以保留当前的信令实现,但只需更改状态的管理方式:状态的FIFO而不是单个变量。