简单的互斥保护队列与C ++中的线程安全队列

时间:2020-06-17 17:36:30

标签: c++ c++11

我想在我的程序中使用一个简单的线程安全std :: queue,它具有多个访问同一队列的线程。我想到的第一件事是使用互斥量保护队列操作,如下所示:

/*Enqueue*/
mutex.lock();
queue.push();
mutex.unlock();

/*Dequeue*/
mutex.lock();
val = queue.front
mutex.unlock();
/*some operation*/
mutex.pop();

我已经看到许多使用条件变量进行线程安全队列实现的健壮实现。 https://stackoverflow.com/a/16075550/3598205。如果只有两个线程访问同一个队列,性能是否会有明显的不同?

2 个答案:

答案 0 :(得分:2)

互斥量和条件变量虽然可以经常一起使用,但它们有两种不同的作用。

为确保一次只有一个线程可以访问资源,请使用互斥锁。您发布的代码显示了一个示例。

要阻塞工作线程直到有事情要做,请让它等待条件变量(然后由提供某种工作项的另一个线程发出信号)。 cppreference上有一个示例。

编写多线程代码时,您首先想到的是编写健壮,安全的代码。犯错很容易,尤其是如果您是该领域的新手,并且由于会导致偶发性的,不可预测的错误,因此很难诊断错误。稍后再担心性能。

答案 1 :(得分:2)

您的申请将受到一件事的限制。我们称其为瓶颈。以我的经验,我所见过的应用程序中有90%受总线带宽的限制,它们将内存转移到主内存/ CPU中或从主内存/ CPU中转移。

不同的应用会有不同的瓶颈。可能是GPU性能或磁盘访问。可能是原始的CPU能力,也可能是争用访问上面的队列。

极有可能,互斥锁将与花哨的无锁队列一样好。但是您不知道,直到您进行配置。

您的应用很可能受到对该队列的访问的严格限制而发生。例如,如果您的应用程序是金融机构的低延迟市场数据交换,并且队列中包含“买/卖”指令,那么它将有所作为。这两个线程可能会不断地写入队列中有数百项的不同位置(因此,在不同的内存页面上)。

或者可能是您的应用程序始终在GPU上等待渲染帧,并且队列中包含玩家武器更改, rendering gameplay 线程只能访问其中的几个每帧次。

个人资料并检查。