如何开发线程安全的生产者/消费者模式?
在我的例子中,生产者在一个线程中运行,而消费者在另一个线程中运行。
std::deque用于此目的安全吗?
我可以在一个线程中push_back到一个双端队列的后面,而在另一个线程中执行push_front吗?
编辑1
在我的例子中,我知道std::deque中的最大项目数(例如10)。有没有办法预先为项目预留足够的空间,以便在处理过程中,不需要更改队列内存的大小,从而确保当我向后添加推送数据时,前面的数据不会发生变化?
发布于 2015-06-11 16:30:09
STL C++容器不是线程安全的:如果您决定使用它们,则在推送/弹出元素时需要使用适当的同步(基本上是std::mutex和std::lock)。
或者,您可以使用适当设计的容器(单生产者-单消费者队列应该能满足您的需求),这里有一个这样的例子:http://www.boost.org/doc/libs/1_58_0/doc/html/lockfree.html
编辑后添加:
是的,SPSC队列基本上就是一个环形缓冲区,非常适合您的需要。
发布于 2015-06-11 16:28:18
如何开发线程安全的生产者/消费者模式?
有几种方法,但使用locks and monitors相当容易掌握,并且没有太多隐藏的注意事项。标准库使用std::unique_lock、std::lock_guard和std::condition_variable来实现该模式。有关简单的示例,请查看condition_variable的of首选项页面。
是std::deque是安全的吗?
这不安全。你需要同步。
是否可以在一个线程中使用push_back连接到双队列的后面,而在另一个线程中使用push_front?
当然可以,但你需要同步。当队列为空或只有一个元素时,存在竞争条件。此外,当队列已满或不足一个,以防您想要限制它的大小。
发布于 2015-06-11 16:29:11
我想你是指push_back()和pop_front()吧。
std::deque本身不是线程安全的。您将需要使用std::mutex序列化访问,这样消费者就不会在生产者尝试推送时尝试弹出。
您还应该考虑如何处理以下问题:
如果它进入等待状态,那么您将需要一个std::condition_variable,以便在添加了该双队列时由生产者通知。您可能还需要处理程序终止,在此过程中,消费者正在等待双队列,而程序被终止。除非你正确地安排了事情,否则它可能会“永远等待”。
10个项目是“无关紧要的”,所以我不会为预留空间而烦恼。std::deque会自动地增长和缩小,所以在构建一个可以工作的应用程序之前,请不要费心进行细粒度调整。
过早优化是万恶之源。
注意:不清楚你是如何限制队列大小的,但是如果生产者填满了队列,然后等待它清空,你将需要更多的等待和条件,以另一种方式来协调。
https://stackoverflow.com/questions/30775277
复制相似问题