我想在我的程序中使用一个简单的线程安全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。如果只有两个线程访问同一个队列,性能是否会有明显的不同?
答案 0 :(得分:2)
互斥量和条件变量虽然可以经常一起使用,但它们有两种不同的作用。
为确保一次只有一个线程可以访问资源,请使用互斥锁。您发布的代码显示了一个示例。
要阻塞工作线程直到有事情要做,请让它等待条件变量(然后由提供某种工作项的另一个线程发出信号)。 cppreference上有一个示例。
编写多线程代码时,您首先想到的是编写健壮,安全的代码。犯错很容易,尤其是如果您是该领域的新手,并且由于会导致偶发性的,不可预测的错误,因此很难诊断错误。稍后再担心性能。
答案 1 :(得分:2)
您的申请将受到一件事的限制。我们称其为瓶颈。以我的经验,我所见过的应用程序中有90%受总线带宽的限制,它们将内存转移到主内存/ CPU中或从主内存/ CPU中转移。
不同的应用会有不同的瓶颈。可能是GPU性能或磁盘访问。可能是原始的CPU能力,也可能是争用访问上面的队列。
极有可能,互斥锁将与花哨的无锁队列一样好。但是您不知道,直到您进行配置。
您的应用很可能受到对该队列的访问的严格限制而发生。例如,如果您的应用程序是金融机构的低延迟市场数据交换,并且队列中包含“买/卖”指令,那么它将有所作为。这两个线程可能会不断地写入队列中有数百项的不同位置(因此,在不同的内存页面上)。
或者可能是您的应用程序始终在GPU上等待渲染帧,并且队列中包含玩家武器更改, rendering 和 gameplay 线程只能访问其中的几个每帧次。
个人资料并检查。