前置問答:html
1.爲何要使用線程池? 避免大量建立和銷燬線程,提高性能。windows
2.線程池主要工做流程?一是外部不斷地向線程池添加任務,而是線程池內部不斷地取任務執行,這是典型的生產者消費者模型。設計模式
3.線程池有幾種類型?半同步半異步線程池 和 領導者追隨者線程池。多線程
第一部分:併發
半同步半異步線程池的工做流程:異步
代碼實現:http://www.itdadao.com/2016/01/18/226136/函數
1.啓動:啓動若干個線程,每一個線程函數內部會循環從任務隊列中取任務,任務隊列的內容就是線程函數的函數名。性能
要點:spa
a. 線程函數是須要傳給線程池對象的,線程池只負責管理線程,並不關心具體的工做線程的任務內容。.net
b. 剛啓動線程池,沒有傳入任何任務時,此時線程池內的全部工做者線程處於阻塞等待狀態(使用條件變量和互斥量),等待任務的到來。使用while(m_running)進行循環等待,當m_running爲false時即爲線程池中止服務時。
2.添加任務:向線程池申請線程執行任務,線程池對象內部會想任務隊列push一個任務。
要點:
a. 向任務隊列push任務時,同步隊列內部會經過條件變量喚醒正在阻塞的等待任務的工做者線程。
條件變量的使用過程以下:
①. 擁有條件變量的線程獲取互斥量;
②. 循環檢查某個條件,若是條件不知足,則阻塞線程直到條件知足。若是條件知足,向下執行;
③. 某個線程知足條件執行完以後調用notify_one或notify_all喚醒一個或全部等待的線程;
b.任務執行結束後,工做者線程繼續陷入等待狀態,直到下一個任務來臨。
3.中止:等待全部線程結束後中止線程池。
要點:
a. 保證中止操做只能被調用一次,須要加鎖;
b. 將同步隊列中止,這樣同步隊列就再也不提供新的任務;
c. 將線程池運行狀態標示m_running置爲中止狀態,保證工做者線程函數再也不等待新任務的到來;
d. 等待全部工做者線程退出後,將線程池內建立好的線程組清空,釋放資源;
關於半同步半異步線程池問答:
1.半同步半異步線程池如何構造的?主要分三層:同步服務層,任務隊列,異步服務層。
2.任務隊列爲何須要設置上限?同步任務隊列若是不加上線控制,會致使排隊任務過多,內存暴漲。
3.生產者過分生產任務時,有什麼影響?任務被處理的等待時間會很長。
參考文檔:
《C++11併發指南三(Lock詳解)》 http://www.cnblogs.com/haippy/p/3346477.html
《四種windows多線程通訊方式》http://blog.csdn.net/bao_qibiao/article/details/4516196
《生產者消費者問題》 https://zh.wikipedia.org/wiki/生產者消費者問題
《領導者跟隨者模式》 http://www.cppblog.com/jerryma/archive/2010/11/11/133325.html
《高性能IO設計模式概述》 http://www.yeolar.com/note/2012/12/15/high-performance-io-design-patterns
期待下一篇:線程池的設計(二):領導者追隨者線程池的設計