把之前做的筆記一次性挪到部落格上好嘍
這是乙個固定數量的執行緒池,執行緒任務可帶引數,非同步返回返回值,本菜雞花了一天才看明白這是怎麼回事,用到了很多c++11的特性,比如bind function future等
class
threadpool
;template
<
classf,
class..
.args>
auto zm::threadpool::
push_task
(f&&f,args&&..
.args)
->std::future<
typename std::result_of<
f(args...
)>
::type>);
}
variable.
notify_one()
;return res;
}zm::threadpool::
threadpool
(int i)
:end
(false))
;if(tasks.
empty()
&&end ==
true
)return
; task = tasks.
front()
; tasks.
pop();
}(task)()
;//執行這個函式 }}
);}}zm::threadpool::
~threadpool()
variable.
notify_all()
;for
(int i=
0;isize()
;++i) threads[i]
.join()
;}
簡述一下執行緒池的實現: 執行緒池類的資料結構包括: 乙個裝有執行緒類的動態vector
乙個互斥鎖用於執行緒訪問共同資源
乙個條件變數用於推送新任務後通知所有執行緒
乙個底層為鍊錶佇列用於裝載推送的任務 (推入型別為空的可呼叫物件)
乙個bool變數 用於關閉所有的執行緒 用於析構
執行緒池類的操作分為三個:
建構函式
push——task
析構函式
建構函式操作包括:
根據構造輸入的引數確定執行緒池的數量,呼叫迴圈,在容器內呼叫emplace——back傳入
乙個可呼叫物件,原地構造乙個執行緒類。
可呼叫物件為乙個死迴圈 :在迴圈內先上鎖 呼叫條件變數wait觀察佇列是否為空以及
是否標記了結束,採用wait第二個引數有兩個好處,第乙個是防止虛假喚醒,第二個是 如果佇列不為空那麼就不在這裡等待了,直接取任務執行。任務被喚醒以後,檢查一下是由於結束被喚醒 還是由於有任務被喚醒,假如有任務被喚醒, 那麼就從佇列裡取出來,然後執行,假如是因為結束被喚醒,那麼就執行return退出執行緒。
push_back函式操作包括:輸入乙個可呼叫物件名,以及一系列的引數,返回乙個future 去獲得這個可呼叫物件的結果 首先呼叫bind函式通過完美**forward將可呼叫物件,以及可呼叫物件傳入的引數繫結在一起 將繫結後的可呼叫物件是沒有形參的,再package_task包裝一下,用於呼叫get_future得到 他的返回型別麼,包裝過程中需要得到可呼叫物件的返回型別的,於是需要result_of模板去提取。
包裝完成後,為這個可呼叫物件分配一篇空間,拿乙個智慧型指標指向這個可呼叫物件。
然後對佇列上鎖 推入乙個可呼叫物件
這個可呼叫物件捕獲了這個pack打包了的指標,然後在邏輯裡面去執行他,所以這個可呼叫物件仍然是void()型別。
喚醒乙個阻塞在條件變數上的執行緒
析構函式包括: 將乙個類內成員end置為 1 並喚醒所有阻塞在條件變數上的執行緒 然後逐一join執行緒。
c 執行緒池的實現
github 傳送門 1.使用例項 測試job寫檔案 class job public wjob job job 1 void run endif 3.wthread 對wthread的封裝,主要在於將之與wjob繫結以完成任務,並與執行緒池繫結,在任務結束後將自己放回空閒佇列 每乙個執行緒都執行r...
執行緒池的c 實現
emmmm,寫這個的主要目的是為了加深對互斥鎖和條件變數的理解,只看unix網路程式設計不實踐一下老覺得心裡沒點底,正好這個東西能練一下而且面試好像也有問到,就手動實現了一下 執行緒池運用的設計模式是命令模式,其原理基本上都能查到這裡就不多說了 直接上 好了 首先是任務類 task.h ifndef...
C 執行緒池的實現
寫了乙個簡易執行緒池,原理簡單介紹下,就是設定乙個任務佇列queue,用來放要執行的函式,還有乙個執行緒陣列vector,用來存放所有的執行緒。執行緒建立以後就存放在相應的vector裡,空閒的執行緒去queue裡去取要執行的函式位址,在run函式中執行,假如乙個執行緒的run函式執行好後,發現佇列...