std::atomic_bool标志的内存顺序

Memory order of an std::atomic_bool flag

本文关键字:内存 顺序 标志 bool atomic std      更新时间:2023-10-16

我正在阅读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。我读到使用默认赋值操作符与使用顺序一致的内存排序相同。

= true。->完成。存储(真的,std:: memory_order_seq_cst)

在这种情况下真的有必要吗?难道使用释放/获取顺序或者甚至是放松的顺序还不够吗?工作线程只是在bool值上循环,显然没有任何其他内存访问可以同步。

是我过度优化还是我错过了什么?

我想你没有误解。顺序一致性访问比最低要求更受约束。

在这种情况下,使用std::atomic::operator=具有简单的优点(即更清晰的代码),并且不太可能引入任何性能问题—特别是在大多数平台上,原子布尔值与处理器操作的映射非常紧密。