【发布时间】:2015-05-18 11:28:39
【问题描述】:
我正在阅读 Anthony Williams 的“C++ Concurrency in Action”,我遇到了这段代码,一个线程池的简单实现。
class thread_pool
{
std::atomic_bool done;
thread_safe_queue<std::function<void()> > work_queue;
std::vector<std::thread> threads;
join_threads joiner;
void worker_thread()
{
while(!done)
{
std::function<void()> task;
if(work_queue.try_pop(task))
{
task();
}
else
{
std::this_thread::yield();
}
}
}
public:
thread_pool():
done(false),joiner(threads)
{
unsigned const thread_count=std::thread::hardware_concurrency();
try
{
for(unsigned i=0;i<thread_count;++i)
{
threads.push_back(
std::thread(&thread_pool::worker_thread,this));
}
}
catch(...)
{
done=true;
throw;
}
}
~thread_pool()
{
done=true;
}
template<typename FunctionType>
void submit(FunctionType f)
{
work_queue.push(std::function<void()>(f));
}
};
附: join_threads 是一个简单的类,它在销毁时连接线程并 thread_safe_queue 是一个……线程安全队列!
我的问题是关于布尔标志 std::atomic_bool done。我读过使用默认赋值运算符与使用 sequentially-consistent memory ordering 相同。
完成=真。 -> done.store(true, std::memory_order_seq_cst)
在这种情况下真的有必要吗?使用发布/获取订单甚至宽松订单还不够吗? 工作线程只是循环 bool 值,显然没有任何其他内存访问要与之同步。
我是过度优化还是错过了什么?
【问题讨论】:
-
析构函数中没有任何其他代码 - 为什么内存顺序的具体选择很重要?
-
线程池构造函数和析构函数不在同一个线程上运行。
标签: c++ multithreading atomic memory-model