亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

C ++ 11中的線程池

C ++ 11中的線程池

C++
莫回無 2019-10-23 16:58:12
我如何獲得一個線程池以將任務發送到,而不是一遍又一遍地創建和刪除它們?這意味著持久性線程無需加入即可重新同步。我有看起來像這樣的代碼:namespace {  std::vector<std::thread> workers;  int total = 4;  int arr[4] = {0};  void each_thread_does(int i) {    arr[i] += 2;  }}int main(int argc, char *argv[]) {  for (int i = 0; i < 8; ++i) { // for 8 iterations,    for (int j = 0; j < 4; ++j) {      workers.push_back(std::thread(each_thread_does, j));    }    for (std::thread &t: workers) {      if (t.joinable()) {        t.join();      }    }    arr[4] = std::min_element(arr, arr+4);  }  return 0;}與其在每個迭代中創建和加入線程,不如在每個迭代中將任務發送到我的工作線程,并且只創建一次。
查看完整描述

3 回答

?
Smart貓小萌

TA貢獻1911條經驗 獲得超7個贊

線程池意味著您所有的線程一直在運行–換句話說,線程函數永遠不會返回。為了使線程有意義,您必須設計一個線程間通信系統,既要告訴線程有事情要做,又要傳達實際的工作數據。

通常,這將涉及某種并發數據結構,并且每個線程可能會休眠在某種條件變量上,在有工作要做時會通知該條件變量。收到通知后,一個或幾個線程將喚醒,從并發數據結構中恢復任務,對其進行處理,并以類似的方式存儲結果。

然后,線程將繼續檢查是否還有更多工作要做,如果還沒有,請回到睡眠狀態。

結果是您必須自己設計所有這一切,因為沒有一種普遍適用的自然的“工作”概念。這需要大量的工作,并且您必須解決一些細微的問題。(如果您喜歡幕后負責線程管理的系統,則可以在Go中編程。)


查看完整回答
反對 回復 2019-10-23
?
人到中年有點甜

TA貢獻1895條經驗 獲得超7個贊

這是從我的答案復制到另一個非常相似的帖子,希望它能對您有所幫助:


1)從系統可以支持的最大線程數開始:


int Num_Threads =  thread::hardware_concurrency();

2)為了有效的線程池的實現,一旦線程根據NUM_THREADS創建,它最好不要創建新的,或破壞舊的(通過連接)。這會降低性能,甚至可能使您的應用程序比串行版本慢。


每個C ++ 11線程都應在其函數中運行一個無限循環,并不斷等待新任務被抓取并運行。


這是將此類功能附加到線程池的方法:


int Num_Threads = thread::hardware_concurrency();

vector<thread> Pool;

for(int ii = 0; ii < Num_Threads; ii++)

{  Pool.push_back(thread(Infinite_loop_function));}

3)Infinite_loop_function


這是一個“ while(true)”循環,正在等待任務隊列


void The_Pool:: Infinite_loop_function()

{

    while(true)

    {

        {

            unique_lock<mutex> lock(Queue_Mutex);


            condition.wait(lock, []{return !Queue.empty() || therminate_pool});

            Job = Queue.front();

            Queue.pop();

        }

        Job(); // function<void()> type

    }

};

4)制作將作業添加到隊列的功能


void The_Pool:: Add_Job(function<void()> New_Job)

{

    {

        unique_lock<mutex> lock(Queue_Mutex);

        Queue.push(New_Job);

    }

    condition.notify_one();

}

5)將任意函數綁定到您的隊列


Pool_Obj.Add_Job(std::bind(&Some_Class::Some_Method, &Some_object));

整合這些成分后,您將擁有自己的動態線程池。這些線程始終運行,等待作業完成。


如果出現語法錯誤,我深表歉意,我鍵入了這些代碼,并且記憶力很差。抱歉,我無法為您提供完整的線程池代碼,因為這會破壞我的工作完整性。


編輯:要終止池,請調用shutdown()方法:


XXXX::shutdown(){

{   unique_lock<mutex> lock(threadpool_mutex);

    terminate_pool = true;} // use this flag in condition.wait


condition.notify_all(); // wake up all threads.


// Join all threads.

for(std::thread &every_thread : thread_vector)

{   every_thread.join();}


thread_vector.empty();  

stopped = true; // use this flag in destructor, if not set, call shutdown() 

}


查看完整回答
反對 回復 2019-10-23
  • 3 回答
  • 0 關注
  • 1039 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號