2016-03-02 52 views
1

據說thread_local每個線程有一個副本。C++併發操作9.6 threadpool使用thread_local

所以,如果線程池(稱爲A)創造另一個線程(稱之爲B),該thread_local變量(local_work_queue)在線程A和B的線程是兩個不同的事情。

所以我迷惑的是,當在池線程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); 
} 
+0

究竟是什麼問題? –

+0

問題是,submit()中的local_work_queue始終爲nullptr,因此線程池無法訪問將任務推送到子線程中的local_work_queue。以及如何解決它? – swtybb

回答

0

,但你做它是靜態的。所以它可以通過課堂進行訪問?超過規則thread_local我假設。

Storage class看到

5)thread_local關鍵字僅允許在命名空間範圍中聲明的對象,在框範圍中聲明的目的,以及靜態數據成員。它表示該對象具有線程存儲持續時間。它可以與靜態或外部結合使用來分別指定內部或外部鏈接(除了總是具有外部鏈接的靜態數據成員外),但是額外的靜態不會影響存儲持續時間。

它的生命時間是線程本地的,但我想連接是類寬。

+0

但我測試它,我不能在不同的線程訪問。 (local_work_queue) local_work_queue-> push(std :: move(task));如果local_work_queue在池線程中始終爲空,則它不能在此步驟中執行。 } – swtybb