消息队列用什么更好?互斥体和条件还是互斥体和信号量?

Ark*_*nez 3 c++ linux multithreading posix

我正在实现一个基于 std::queue 的 C++ 消息队列。

由于我需要 popers 等待空队列,因此我正在考虑使用 mutex 进行互斥,并使用 cond 来挂起空队列上的线程,就像 glib 对 gasyncqueue 所做的那样。

然而,在我看来,互斥体和信号量可以完成这项工作,我认为它包含一个整数,并且对于待处理的消息来说,这似乎是一个相当高的数字。

信号量的优点是,您不需要每次从等待返回时手动检查条件,因为您现在可以确定有人插入了某些内容(当有人插入了 2 个项目并且您是第二个到达的线程时)。

你会选哪一个?

编辑:更改了响应@Greg Rogers 的问题

Gre*_*ers 5

单个信号量无法完成这项工作 - 您需要比较(mutex + semaphore)和(mutex + 条件变量)。

通过尝试实现它很容易看出这一点:

void push(T t)
{
    queue.push(t); 
    sem.post();
}

T pop()
{
    sem.wait();
    T t = queue.top();
    queue.pop();
    return t;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,当您实际读取/写入队列时,即使存在信号(来自信号量),也不会出现互斥。多个线程可以同时调用push并打破队列,或者多个线程可以同时调用pop并打破队列。或者,一个线程可以调用 pop 并删除队列的第一个元素,而另一个线程则调用 push。

您应该使用您认为更容易实现的任何一个,我怀疑性能会有很大差异(如果有的话)(尽管测量可能很有趣)。