STL队列的线程安全性

Ste*_*eng 19 c++ multithreading stl

我正在使用队列来在线程之间进行通信.我有一个读者和多个编写器线程.我的问题是,每当我从队列中使用push/front/pop进行读取时,我是否需要锁定队列?我可以做以下事情:

//reader threads
getLock();
get the number of elements from the queue
releaseLock();

int i = 0;
while( i < numOfElements){
    queue.front();
    queue.pop();
    i++
}
Run Code Online (Sandbox Code Playgroud)

我的想法是,我希望减少锁定代码的粒度,因为编写器线程只会写入队列的后面,并且只有一个读取器线程.只要我得到的元素个数,然后我能得到从队列中的元素或者我需要封闭front(),并pop()在锁呢?

Pra*_*ian 10

正如其他人已经提到的那样,标准容器不需要保证线程安全,因此您所要求的内容无法实现.您可以通过使用2个队列和一个指示编写器当前正在使用的队列的队列指针来缩短读取器线程锁定写入器的时间.

每位作家都会:

  • 获取锁定
  • 将元素推入队列指针当前指向的队列中
  • 解锁

然后读者可以执行以下操作:

  • 获取锁定
  • 切换队列指针指向第二个队列
  • 解锁
  • 处理第一个队列中的元素

  • 编写器将始终附加到队列指针当前指向的任何队列(在首次获取锁之后).在这种情况下,锁保护指针当前引用的任何队列(以及指针本身); 另一个队列("第一队列")可以由读者处理,无需持有锁. (2认同)

小智 9

任何未明确声明其线程安全保证的类型应始终由互斥锁控制.也就是说,你的实现的stdlib可能允许一些变化 - 但你不能知道std :: queue的所有实现.

当std :: queue包装另一个容器(它是容器适配器)时,您需要查看底层容器,默认为deque.

您可能会发现编写自己的容器适配器更容易,更好或更便携,从而提供所需的保证.我不知道为Boost中的队列做了什么.

我没有看过C++ 0x足以知道它是否有任何开箱即用的解决方案,但这可能是另一种选择.

  • C++ 0x具有原子,因此它使程序员能够编写无锁(线程安全)算法,并提供标准互斥锁,但它没有任何开箱即用的功能. (4认同)