C++ 操作 9.6 线程池中的并发使用thread_local

C++ Concurrency in Action 9.6 threadpool use thread_local

本文关键字:并发 thread local 操作 线程 C++      更新时间:2023-10-16
据说

,thread_local,每个线程有一个副本。

所以如果 threadPool(称它为 A)的线程创建了另一个线程(称它为 B),则线程 A 和 B 中的thread_local变量(local_work_queue)是两回事。

所以我混淆了当池线程 A(int main())中的池峰会任务时,它如何访问子线程 B 中的local_work_queue??? 它们完全无关紧要。

函数提交在池线程中,local_work_queue只在 sub thred 中初始化,所以在提交函数中,local_work_queue将始终为 nullptr,不是吗?

下面是代码:

class thread_pool
{
    typedef std::queue<function_wrapper> local_queue_type;
    static thread_local std::unique_ptr<local_queue_type> local_work_queue;
    std::vector<std::thread> threads;`
    thread_pool()
    {
        unsigned const thread_count=std::thread::hardware_concurrency();
        for(unsigned i=0;i<thread_count;++i)
        {
            threads.push_back(
            std::thread(&thread_pool::worker_thread,this,i));
        }
    }
    void worker_thread()
    {
        local_work_queue.reset(new local_queue_type);  //just init in the sub thread
        while(1)
        {
            function_wrapper task;
            if(local_work_queue && !local_work_queue->empty())
            {
                task=std::move(local_work_queue->front());
                local_work_queue->pop();
                task();
            }
            else
            {
                std::this_thread::yield();
            }
        }
    }
    template<typename FunctionType>
    std::future<typename std::result_of<FunctionType()>::type>submit(FunctionType f)
    {
        typedef typename std::result_of<FunctionType()>::type result_type;
        std::packaged_task<result_type()> task(f);
        std::future<result_type> res(task.get_future());
        if(local_work_queue) //function submit is in pool thread, and local_work_queue only init in sub thred, so in this ,local_work_queue will away nullptr, isn't it? so confuse how the code work.
        {
            local_work_queue->push(std::move(task));
        }
        return res;
    }
};
void func()
{
    std::cout<<"test"<<std::endl;
}
int main()
{
    thread_pool p;
    p.submit(func);
}

但你把它变成了静态的。所以它可以通过课堂访问吗?这凌驾于我假设的thread_local之上。

请参阅存储类

5) thread_local 关键字只允许用于在命名空间范围内声明的对象、在块范围内声明的对象和静态数据成员。它指示对象具有线程存储持续时间。它可以与 static 或 extern 结合使用,分别指定内部或外部链接(始终具有外部链接的静态数据成员除外),但额外的静态不会影响存储持续时间。

它的生命周期是线程本地的,但我想链接是类范围的。