我正在尝试在pthreads中实现单写,多读队列。同步模式有效,但在重复请求后最终会死锁(我相信)。它可以无限期地使用一个writer boss线程和一个reader worker线程,但是如果我只有一个writer boss线程和多个reader worker线程,它将最终挂起。当我在gdb中回溯时,我看到了:
// Boss:
Thread 1 (Thread 0x7ffff7fd1780 (LWP 21029)):
#0 0x00007ffff7bc44b0 in futex_wait
...
// Worker:
Thread 2 (Thread 0x7ffff42ff700 (LWP 21033)):
#0 0x00007ffff7bc39f3 in futex_wait_cancelable
...
// Worker:
Thread 3 (Thread 0x7ffff3afe700 (LWP 21034)):
#0 0x00007ffff7bc39f3 in futex_wait_cancelable
...
在我看来,这似乎是工人在等待信号,而老板正在悬挂信号而不发送信号。但是,我不知道为什么会这样。
我已经尝试过这种同步模式:
// Boss:
pthread_mutex_lock(&queue_mutex);
queue_push(&queue, data);
pthread_cond_signal(&queue_condition);
pthread_mutex_unlock(&queue_mutex);
return;
// Worker(s):
pthread_mutex_lock(&queue_mutex);
while((queue_isempty(&queue)) > 0) {
pthread_cond_wait(&queue_condition, &queue_mutex);
}
data_t *data = queue_pop(&queue);
pthread_mutex_unlock(&queue_mutex);
do_work(data);
据我所知,这是正确的同步模式。但是,证据表明我没有采用正确的模式。有人可以帮我理解为什么pthread中的这种单写,多读队列访问无法按我的预期工作吗?
最佳答案
这是基于可用代码的最佳猜测。死锁可能是由于工人在等待信号时握住锁而老板没有机会握住锁(在工人握住锁以发送信号时)。以下应避免死锁。
// Boss:
pthread_mutex_lock(&queue_mutex);
queue_push(&queue, data);
pthread_mutex_unlock(&queue_mutex);
pthread_cond_signal(&queue_condition);
return;
// Worker(s):
while((queue_isempty(&queue)) > 0) { //> assume queue_isempty(const void*);
pthread_cond_wait(&queue_condition, &queue_mutex);
}
pthread_mutex_lock(&queue_mutex);
data_t *data = queue_pop(&queue);
pthread_mutex_unlock(&queue_mutex);
do_work(data);