在C ++ 11中,在线程之间高效安全地传递不可变对象

时间:2014-03-17 12:57:02

标签: c++ multithreading c++11 thread-safety

考虑到Producer Thread创建任意类型o的对象O然后必须由Consumer Thread读取(并且仅读取)的情况,这是template<typename T> class WorkQueue { std::list<T> queue; std::mutex mut; std::condition_variable cond; public: ... } 在C ++ 11中以高效且线程安全的方式实现这一目标的理想方法?

截至目前,我的实现依赖于生产者 - 消费者模型,使用基于模板的互斥/条件化工作队列:

o

如果class WorkItem { const int value; public: WorkItem(int v) : value(v) {} const int getValue() { return value; } } 的类型定义如下:

WorkItem

并且线程在堆中生成消耗WorkQueue<WorkItem*> workQueue; ... void producerThread() { workQueue.add(new WorkItem(0)); } void consumerThread() { WorkItem *item = workQueue.remove(); doSomething(item.getValue()); delete item; } 对象,如下所示:

{{1}}

我是否保证消费者可以正确阅读堆对象?

如果答案恰好为否,我猜测WorkItem的成员应该受到互斥锁的保护,但这将是一个非常低效的解决方案,因为在WorkItem之后不需要锁定已经提供给所有线程。或者,我猜测在这种情况下基于雾化的方法会更好。

1 个答案:

答案 0 :(得分:0)

你的建议看起来不错。您可以存储智能指针,例如std::unique_ptr<WorkItem>,以获得异常安全,例如: doSomething()抛出。您应该知道无锁队列,但您不一定需要使用一个,特别是如果它意味着向您的项目添加新的库依赖项。最后,所有new内存分配有一天可能成为瓶颈,在这种情况下,请查看使用对象池或以其他方式重用您的WorkItems。但是现在大多数事情都是过早的优化。