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

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

C ++ 11中的線程池

C ++ 11中的線程池

C++
拉丁的傳說 2019-12-10 12:08:24
我如何獲得一個線程池以將任務發送到,而不是一遍又一遍地創建和刪除它們?這意味著持久性線程無需加入即可重新同步。我有看起來像這樣的代碼: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 回答

?
月關寶盒

TA貢獻1772條經驗 獲得超5個贊

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

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

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

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



查看完整回答
反對 回復 2019-12-11
?
暮色呼如

TA貢獻1853條經驗 獲得超9個贊

希望它能對您有所幫助:


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-12-11
  • 3 回答
  • 0 關注
  • 345 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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