簡述Linux C下執行緒池的使用

2021-10-19 12:09:01 字數 4072 閱讀 8280

執行緒池也是多執行緒的處理方式。是將「生產者」執行緒提出任務新增到「任務佇列」,然後一些執行緒自動完成「任務佇列」上的任務。

多執行緒程式設計,建立乙個執行緒,指定去完成某乙個任務,等待執行緒的退出。雖然能夠滿足程式設計需求,但是當我們需要建立大量的執行緒的時候,在建立過程以及銷毀執行緒的過程中可能會消耗大量的cpu.增加很大開銷。如:資料夾的copy、web伺服器的響應。

執行緒池就是用來解決類似於這樣的乙個問題的,可以降低頻繁地建立和銷毀執行緒所帶來地開銷。

執行緒池技術思路:一般採用預建立執行緒技術,也就是提前把需要用執行緒先建立一定數目。這些執行緒提前建立好了之後,「任務佇列」裡面假設沒有任務,那麼就讓這些執行緒休眠,一旦有任務,就喚醒執行緒去執行任務,任務執行完了,也不需要去銷毀執行緒,直到當你想退出或者是關機時,這個時候,那麼你呼叫銷毀執行緒池地函式去銷毀執行緒。

執行緒完成任務之後不會銷毀,而是自動地執行下乙個任務。而且,當任務有很多,你可以有函式介面去增加執行緒數量,當任務較少時,你可以有函式介面去銷毀部分執行緒。

如果,建立和銷毀執行緒的時間對比執行任務的時間可以忽略不計,那麼我們在這種情況下面也就沒有必要用執行緒池。

「任務佇列」是乙個共享資源「互斥訪問」

執行緒池本質上也是乙個資料結構,需要乙個結構體去描述它:

struct pthread_pool //執行緒池的實現 ;  

//任務佇列(鍊錶)上面的任務結點,只要能夠描述好乙個任務就可以了,

//執行緒會不斷地任務佇列取任務

struct task //任務結點

;

執行緒池框架**如下,功能自填:

操作執行緒池所需要的函式介面:pthread_pool.c 、pthread_pool.h

把「執行緒池」想象成乙個外包公司,你需要去完成的就是操作執行緒池所提供的函式介面。

pthread_pool.c

#include "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)

pthread_pool.h

#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 ...