執行緒池也是多執行緒的處理方式。是將「生產者」執行緒提出任務新增到「任務佇列」,然後一些執行緒自動完成「任務佇列」上的任務。
多執行緒程式設計,建立乙個執行緒,指定去完成某乙個任務,等待執行緒的退出。雖然能夠滿足程式設計需求,但是當我們需要建立大量的執行緒的時候,在建立過程以及銷毀執行緒的過程中可能會消耗大量的cpu.增加很大開銷。如:資料夾的copy、web伺服器的響應。
執行緒池就是用來解決類似於這樣的乙個問題的,可以降低頻繁地建立和銷毀執行緒所帶來地開銷。
執行緒池技術思路:一般採用預建立執行緒技術,也就是提前把需要用執行緒先建立一定數目。這些執行緒提前建立好了之後,「任務佇列」裡面假設沒有任務,那麼就讓這些執行緒休眠,一旦有任務,就喚醒執行緒去執行任務,任務執行完了,也不需要去銷毀執行緒,直到當你想退出或者是關機時,這個時候,那麼你呼叫銷毀執行緒池地函式去銷毀執行緒。
執行緒完成任務之後不會銷毀,而是自動地執行下乙個任務。而且,當任務有很多,你可以有函式介面去增加執行緒數量,當任務較少時,你可以有函式介面去銷毀部分執行緒。
如果,建立和銷毀執行緒的時間對比執行任務的時間可以忽略不計,那麼我們在這種情況下面也就沒有必要用執行緒池。
「任務佇列」是乙個共享資源「互斥訪問」
執行緒池本質上也是乙個資料結構,需要乙個結構體去描述它:
struct pthread_pool //執行緒池的實現 ;執行緒池框架**如下,功能自填://任務佇列(鍊錶)上面的任務結點,只要能夠描述好乙個任務就可以了,
//執行緒會不斷地任務佇列取任務
struct task //任務結點
;
操作執行緒池所需要的函式介面:pthread_pool.c 、pthread_pool.h
把「執行緒池」想象成乙個外包公司,你需要去完成的就是操作執行緒池所提供的函式介面。
pthread_pool.c
#include "pthread_pool.h"pthread_pool.h/* init_pool: 執行緒池初始化函式,初始化指定的執行緒池中有thread_num個初始執行緒
@pool:指標,指向您要初始化的那個執行緒池
@threa_num: 您要初始化的執行緒池中開始的執行緒數量
返回值:
成功 0
失敗 -1
*/
int init_pool(pthread_pool * pool , unsigned int threa_num)
pool->task_list->next = null;
//執行緒池中一開始初始化多少個執行緒來服役
pool->active_threads = threa_num;
//表示執行緒池中最多有多少個任務
pool->max_waiting_tasks = max_waiting_tasks;
//執行緒池中任務佇列當前的任務數量
pool->cur_waiting_tasks = 0;
//建立thread_num個執行緒,並且讓執行緒去執行任務調配函式,
//記錄所有執行緒的tid
int i = 0;
for(i = 0; i < threa_num; i++)
printf("[%lu]:[%s] ===> tids[%d]:[%lu]",pthread_self(),
__function__, i , pool->tids[i]);
} return 0; }
/* routine: 任務調配函式。
所有執行緒開始都執行此函式,此函式會不斷的從執行緒池的任務佇列
中取下任務結點,去執行。
任務結點中包含「函式指標」 h "函式引數"
*/
void * routine(void * arg) }
/* destroy_pool: 銷毀執行緒池,銷毀前要保證所有的任務已經完成
*/
int destroy_pool(pthread_pool * pool)
/* add_task:給任務佇列增加任務, 把do_task指向的任務(函式指標)和
arg指向的引數儲存到乙個任務結點,新增到pool任務佇列中。
@pool : 您要新增任務的執行緒池
@do_task : 您需要新增的任務(cp_file)
@arg: 您要執行的任務的引數(檔案描述符)
*/
int add_task(pthread_pool *pool,void*(* do_task)(void * arg), void*arg)
//如果任務多的時候,往執行緒池中新增執行緒 pthread_create
int add_threads(pthread_pool * pool, unsigned int num);
//如果任務少的時候,減少執行緒池中線程的數量 pthread_cancel join
int remove_threads(pthread_pool * pool, unsigned int num)
#ifndef __pthread_pool_h__#define __pthread_pool_h__
//表示執行緒池中最多有多少個執行緒
#define max_active_threads 20
//表示執行緒池中最多有多少個任務
#define max_waiting_tasks 1024
//任務佇列(鍊錶)上面的任務結點,只要能夠描述好乙個任務就可以了,
//執行緒會不斷地任務佇列取任務
struct task //任務結點 ;
struct pthread_pool //執行緒池的實現 ;
/* init_pool: 執行緒池初始化函式,初始化指定的執行緒池中有thread_num
個初始執行緒
@pool:指標,指向您要初始化的那個執行緒池
@threa_num: 您要初始化的執行緒池中開始的執行緒數量
返回值:
成功 0
失敗 -1
*/
int init_pool(pthread_pool * pool , unsigned int threa_num);
/* routine: 任務調配函式。
所有執行緒開始都執行此函式,此函式會不斷的從執行緒池的任務佇列
中取下任務結點,去執行。
任務結點中包含「函式指標」 h "函式引數"
*/
void * routine(void * arg);
/* destroy_pool: 銷毀執行緒池,銷毀前要保證所有的任務已經完成
*/
int destroy_pool(pthread_pool * pool);
/* add_task:給任務佇列增加任務, 把do_task指向的任務(函式指標)和
arg指向的引數儲存到乙個任務結點,新增到pool任務佇列中。
@pool : 您要新增任務的執行緒池
@do_task : 您需要新增的任務(cp_file)
@arg: 您要執行的任務的引數(檔案描述符)
*/
int add_task(pthread_pool *pool,void*(* do_task)(void * arg), void*arg);
//如果任務多的時候,往執行緒池中新增執行緒 pthread_create
int add_threads(pthread_pool * pool, unsigned int num);
//如果任務少的時候,減少執行緒池中線程的數量 pthread_cancel join
int remove_threads(pthread_pool * pool, unsigned int num);
#endif
簡述執行緒池
首先我們來了解下執行緒池的相關概念,執行緒池是什麼。池,是容器,那顧名思義執行緒池就是管理執行緒的容器。很自然的我們會引出乙個問題,就是為什麼要使用執行緒池,而不是自己去管理多執行緒?在多執行緒應用場景中,會不斷建立和銷毀新的執行緒,而這會耗費大量的io資源,這樣過度消耗系統資源則有可能會導致系統奔...
linux C實現執行緒池
執行緒池包括任務佇列,執行緒陣列,管理模組幾個部分,依次實現這幾個模組 typedef struct tk tasktk task t 任務佇列,用單鏈表的方式實現 執行緒池的管理模組用以下 typedef struct threadpooltk threadpool t 要實現以下幾個方法 tk ...
linux下執行緒池的實現(c )
2012 12 07 16 11 44 分類 電子安防專案 舉報 字型大小訂閱 參考 autoptr.h created on 2012 12 7 author kym 智慧型指標模板 ifndef autoptr h define autoptr h include template class ...