考虑到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之后不需要锁定已经提供给所有线程。或者,我猜测在这种情况下基于雾化的方法会更好。
答案 0 :(得分:0)
你的建议看起来不错。您可以存储智能指针,例如std::unique_ptr<WorkItem>
,以获得异常安全,例如: doSomething()
抛出。您应该知道无锁队列,但您不一定需要使用一个,特别是如果它意味着向您的项目添加新的库依赖项。最后,所有new
内存分配有一天可能成为瓶颈,在这种情况下,请查看使用对象池或以其他方式重用您的WorkItems。但是现在大多数事情都是过早的优化。