我正在尝试在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);

09-15 15:25