【问题标题】:C++ Concurrency in Action 9.6 threadpool use thread_localC++ Concurrency in Action 9.6 线程池使用 thread_local
【发布时间】:2016-06-15 05:20:49
【问题描述】:

据说,thread_local,每个线程一个副本。

所以如果threadPool的线程(称为A)创建另一个线程(称为B),线程A和B中的thread_local变量(local_work_queue)是两个不同的东西。

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

函数提交在池线程中,而local_work_queue只在子线程中初始化,所以在提交函数中,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);
}

【问题讨论】:

  • 你的问题到底是什么?
  • 问题是,subthread()中的local_work_queue总是nullptr,所以线程池无法访问到子线程中的local_work_queue推送任务。以及如何解决?

标签: c++ multithreading concurrency threadpool thread-local


【解决方案1】:

但是你把它变成了静态的。那么它可以通过类访问吗?这超过了我假设的 thread_local 。

Storage class

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

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

【讨论】:

  • 但我测试了它,我无法在不同的线程中访问。池线程中的 local_work_queue 始终为空,不能在此执行: if(local_work_queue) { local_work_queue->push(std::move(task)); }
猜你喜欢
  • 2016-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-24
  • 1970-01-01
  • 2021-09-18
  • 2013-02-19
相关资源
最近更新 更多