3 回答

TA貢獻1772條經驗 獲得超5個贊
線程池意味著您所有的線程一直在運行–換句話說,線程函數永遠不會返回。為了使線程有意義,您必須設計一個線程間通信系統,既要告訴線程有事情要做,又要傳達實際的工作數據。
通常,這將涉及某種并發數據結構,并且每個線程可能會休眠在某種條件變量上,在有工作要做時會通知該條件變量。收到通知后,一個或幾個線程將喚醒,從并發數據結構中恢復任務,對其進行處理,并以類似的方式存儲結果。
然后,線程將繼續檢查是否還有更多工作要做,如果還沒有,請回到睡眠狀態。
結果是您必須自己設計所有這一切,因為沒有一種普遍適用的自然的“工作”概念。這需要大量的工作,并且您必須解決一些細微的問題。(如果您喜歡幕后負責線程管理的系統,則可以在Go中編程。)

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()?
}
- 3 回答
- 0 關注
- 345 瀏覽
添加回答
舉報