首先問三個問題:什麼是執行緒池?執行緒池的優勢是什麼?實現原理是什麼?
字面意思就是」乙個存放執行緒的池塘」,類似於記憶體池的概念,建立固定數量的執行緒,來處理多個任務,執行緒執行完乙個任務後不銷毀而是繼續執行下乙個任務,這樣就避免了執行緒的頻繁建立和銷毀,大大提高了效率(和多執行緒相模型相比),這也回答了第二個問題,執行緒池的優勢所在。
執行緒池不只有乙個執行緒組,還需要乙個任務佇列來方便執行緒池獲取任務,此任務隊列為被所有執行緒共享,因此在考慮類的資料結構是必須新增進來,另外,因為有多個執行緒共享乙個資源的情況(都會訪問任務佇列),還必須要考慮加鎖的問題。借用一張圖來說明執行緒池的工作流程:
首先是執行緒同步的類封裝condition.h:
#ifndef mythreadpool_condition_h
#define mythreadpool_condition_h
#include
//封裝乙個互斥量和條件變數作為狀態
typedef struct condition
condition_t;
class
condition_mutex
;#endif //mythreadpool_condition_h
具體實現condition.cpp:
#include "condition.h"
condition_mutex::condition_mutex()
condition_mutex::~condition_mutex()
//初始化
int condition_mutex::condition_init()
//加鎖
int condition_mutex::condition_lock()
//解鎖
int condition_mutex::condition_unlock()
//等待
int condition_mutex::condition_wait()
//固定時間等待
int condition_mutex::condition_timedwait(const
struct timespec *abstime)
//喚醒乙個睡眠執行緒
int condition_mutex::condition_signal()
//喚醒所有睡眠執行緒
int condition_mutex::condition_broadcast()
//釋放
int condition_mutex::condition_destroy()
接下來是執行緒池結構的封裝threadpool.h:
#ifndef mythreadpool_threadpool_h
#define mythreadpool_threadpool_h
//執行緒池標頭檔案
#include "condition.h"
//封裝執行緒池中的物件需要執行的任務物件
typedef struct task
task_t;
//下面是執行緒池結構體
typedef struct threadpool_data
threadpool_t;
class
threadpool
;#endif //mythreadpool_threadpool_h
執行緒池實現threadpool.cpp:
#include "threadpool.h"
#include
#include
#include
#include
#include
//建立的執行緒執行
static
void *thread_routine(void *arg)
}pool->idle--;
if(pool->first != null)
//退出執行緒池
if(pool->quit && pool->first == null)
pool->ready.condition_unlock();
break;
}//超時,跳出銷毀執行緒
if(timeout == 1)
pool->ready.condition_unlock();
}printf("thread %d is exiting\n", pthread_self());
return null;
}threadpool::threadpool(int threads)
threadpool::~threadpool()
//執行緒池初始化
void threadpool::threadpool_init(int threads)
//增加乙個任務到執行緒池
void threadpool::threadpool_add_task(void *(*run)(void *arg), void *arg)
else
workers.last = newtask; //佇列尾指向新加入的執行緒
//執行緒池中有執行緒空閒,喚醒
if(workers.idle > 0)
//當前執行緒池中線程個數沒有達到設定的最大值,建立乙個新的執行緒
else
if(workers.counter < workers.max_threads)
//結束,訪問
workers.ready.condition_unlock();
}//執行緒池銷毀
void threadpool::threadpool_destroy()
//加鎖
workers.ready.condition_lock();
//設定銷毀標記為1
workers.quit = 1;
//執行緒池中線程個數大於0
if(workers.counter > 0)
//正在執行任務的執行緒,等待他們結束任務
while(workers.counter)
}workers.ready.condition_unlock();
workers.ready.condition_destroy();
}
測試程式:
#include "threadpool.h"
#include
#include
#include
void* mytask1(void *arg)
void* mytask2(void *arg)
//測試**
int main(void)
int *arg = (int *)malloc(sizeof(int));
*arg = i;
if (i%2 == 0)
else
}return
0;}
執行結果分析:
在本測試程式中,主線程(即程序本身)連續建立了三個執行緒,6139904(暫記為1號執行緒),6676480(2號執行緒),7213056(3號執行緒),且不停地在向任務佇列中新增任務,從圖中看到,1號執行緒執行了任務0,2號執行緒執行了任務1,3號執行緒執行了任務2,由於奇數任務的執行時間較長(mytask2,休眠10秒鐘),1號執行緒和3號執行緒結束的比較快,又開始獲取新的任務,3號執行緒獲取任務3,進入長時間的休眠中,此時1號執行緒處理完任務4之後,繼續處理任務5,發現任務佇列已空,且輪詢等待2秒之後沒有獲取到新的任務,退出執行緒並銷毀。之後5號任務加入了佇列,執行緒池又重新建立了7213056(4號執行緒),……
從執行緒的執行時序可以看出,本執行緒池很好的完成了多工的執行緒分配,且執行沒有問題,封裝簡單易用。
參考原文:
乙個簡單的執行緒池
話說這個執行緒池也寫了好久了 做簡單的東西的時候也在用,最近因為乙個失誤刪掉了自己的一些檔案導致重新寫了一遍 所以貼出來,以防萬一 並且跟大佬們交流 created by cxhmyself on 18 4 10.include 都需要與互斥量一起才能工作 include include inclu...
乙個簡單的執行緒池
最近自己,很煩所以超級久沒學習了,今天趁著抗戰七十周年放三天假,趕緊看下書。廢話不多說。今天,介紹乙個簡單的執行緒池。首先說明什麼是執行緒池,執行緒池 是包含若干個執行緒,來處理多個任務的執行緒集合。它的目的是用來處理,大量的相對短暫的任務。這裡我們先來解釋下兩個概念,什麼叫大量呢?對於執行緒來說,...
封裝乙個簡單的池操作
臨界區同步類 class cmrthreadlock 析構函式 inline cmrthreadlock 功能函式 public 鎖定函式 virtual inline void lock 解鎖函式 virtual inline void unlock class cmrpoolobject cla...