91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

如何分析Linux 下線程池的使用

發布時間:2022-01-24 11:50:59 來源:億速云 閱讀:131 作者:柒染 欄目:開發技術

這期內容當中小編將會給大家帶來有關如何分析Linux 下線程池的使用,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。

處理多線程的方式可以采用線程池,可以將“生產者”線程提出任務列表添加到“任務列表”,然后一些線程自動完成“任務隊列”的任務。

多線程編程,創建一個線程,指定去完成某一個任務,等待線程的退出。雖然能夠滿足編程需求,但是當我們需要創建大量的線程的時候,在創建過程以及銷毀線程的過程中可能會消耗大量的CPU.增加很大開銷。如:文件夾的copy、WEB服務器的響應。

線程池就是用來解決類似于這樣的一個問題的,可以降低頻繁地創建和銷毀線程所帶來地開銷。

線程池技術思路:一般采用預創建線程技術,也就是提前把需要用線程先創建一定數目。這些線程提前創建好了之后,“任務隊列”里面假設沒有任務,那么就讓這些線程休眠,一旦有任務,就喚醒線程去執行任務,任務執行完了,也不需要去銷毀線程,直到當你想退出或者是關機時,這個時候,那么你調用銷毀線程池地函數去銷毀線程。

線程完成任務之后不會銷毀,而是自動地執行下一個任務。而且,當任務有很多,你可以有函數接口去增加線程數量,當任務較少時,你可以有函數接口去銷毀部分線程。

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

“任務隊列”是一個共享資源“互斥訪問”

如何分析Linux 下線程池的使用

線程池本質上也是一個數據結構,需要一個結構體去描述它:

struct pthread_pool //線程池的實現 
{ 
 //一般會有如下成員 
 
 //互斥鎖,用來保護這個“任務隊列” 
 pthread_mutex_t lock; //互斥鎖  
  
 //線程條件變量 表示“任務隊列”是否有任務 
 pthread_cond_t cond; //條件變量 
  
 bool shutdown; //表示是否退出程序 bool:類型 false / true 
 
 //任務隊列(鏈表),指向第一個需要指向的任務 
 //所有的線程都從任務鏈表中獲取任務 "共享資源" 
 struct task * task_list; 
  
 //線程池中有多個線程,每一個線程都有tid, 需要一個數組去保存tid 
 pthread_t * tids; //malloc()  
  
 //線程池中正在服役的線程數,當前線程個數 
 unsigned int active_threads; 
  
 //線程池任務隊列最大的任務數量 
 unsigned int max_waiting_tasks; 
  
 //線程池任務隊列上當前有多少個任務 
 unsigned int cur_waiting_tasks; 
  
 //...... 
 
}; 
 
//任務隊列(鏈表)上面的任務結點,只要能夠描述好一個任務就可以了, 
//線程會不斷地任務隊列取任務 
struct task  //任務結點  
{ 
 // 1. 任務結點表示的任務,“函數指針”指向任務要執行的函數(cp_file) 
 void*(* do_task)(void * arg); 
  
 //2. 指針,指向任務指向函數的參數(文件描述符) 
 void * arg; 
  
 //3. 任務結點類型的指針,指向下一個任務 
 struct task * next; 
};

線程池框架代碼如下,功能自填:

操作線程池所需要的函數接口: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) 
{ 
 //初始化線程池的結構體 
  
 //初始化線程互斥鎖 
 pthread_mutex_init(&pool->lock, NULL); 
  
 //初始化線程條件變量 
 pthread_cond_init(&pool->cond, NULL); 
 
 pool->shutdown = false ;// 不退出 
 
 pool->task_list = (struct task*)malloc(sizeof(struct task)); 
 
 pool->tids = (pthread_t *)malloc(sizeof(pthread_t) * MAX_ACTIVE_THREADS); 
 if(pool->task_list == NULL || pool->tids == NULL) 
 { 
  perror("malloc memery error"); 
  return -1; 
 } 
 
 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 tids)[i], NULL, routine, (void*)pool); 
  if(ret != 0) 
  { 
   perror("create thread error"); 
   return -1; 
  } 
 
  printf("[%lu]:[%s] ===> tids[%d]:[%lu]",pthread_self(), 
   __FUNCTION__, i , pool->tids[i]); 
 } 
 
 return 0; 
} 
 
/* 
 routine: 任務調配函數。 
  所有線程開始都執行此函數,此函數會不斷的從線程池的任務隊列 
  中取下任務結點,去執行。 
   
  任務結點中包含“函數指針” h "函數參數" 
*/ 
 
void * routine(void * arg) 
{ 
 //arg表示你的線程池的指針 
  
 while() 
 { 
  //獲取線程互斥鎖,lock  
   
  //當線程池沒有結束的時候,不斷地從線程池的任務隊列取下結點 
  //去執行。 
   
  //釋放線程互斥鎖,unlock 
   
  //釋放任務結點 
 } 
} 
 
/* 
 destroy_pool: 銷毀線程池,銷毀前要保證所有的任務已經完成 
*/ 
 
int destroy_pool(pthread_pool * pool) 
{ 
 //釋放所有空間 等待任務執行完畢(join)。 
 //喚醒所有線程 
 //利用join函數回收每一個線程資源。 
} 
 
/* 
 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) 
{ 
 //把第二個參數和第三個參數封裝成struct task  
  
 //再把它添加到 pool->task 任務隊列中去 
  
 //注意任務隊列是一個共享資源 
  
 //假如任務后要喚醒等待的線程。 
} 
 
//如果任務多的時候,往線程池中添加線程  pthread_create 
int add_threads(pthread_pool * pool, unsigned int num); 
{ 
 //新創建num個線程,讓每一個線程去執行線程調配函數 
  
 //將每一個新創建的線程tid,添加到pool-> tids  
} 
 
//如果任務少的時候,減少線程池中線程的數量 pthread_cancel join 
int remove_threads(pthread_pool * pool, unsigned int num) 
{ 
 //用pthread_cancel取消num個線程  
 //利用pthread_join函數去回收資源。 
}
pthread_pool.h

#ifndef __PTHREAD_POOL_H__ 
#define __PTHREAD_POOL_H__ 
 
//表示線程池中最多有多少個線程 
#define MAX_ACTIVE_THREADS 20 
 
//表示線程池中最多有多少個任務 
#define MAX_WAITING_TASKS 1024 
 
//任務隊列(鏈表)上面的任務結點,只要能夠描述好一個任務就可以了, 
//線程會不斷地任務隊列取任務 
struct task  //任務結點  
{ 
 // 1. 任務結點表示的任務,“函數指針”指向任務要執行的函數(cp_file) 
 void*(* do_task)(void * arg); 
  
 //2. 指針,指向任務指向函數的參數(文件描述符) 
 void * arg; 
  
 //3. 任務結點類型的指針,指向下一個任務 
 struct task * next; 
}; 
 
struct pthread_pool //線程池的實現 
{ 
 //一般會有如下成員 
 
 //互斥鎖,用來保護這個“任務隊列” 
 pthread_mutex_t lock; //互斥鎖  
  
 //線程條件變量 表示“任務隊列”是否有任務 
 pthread_cond_t cond; //條件變量 
  
 bool shutdown; //表示是否退出程序 bool:類型 false / true 
 
 //任務隊列(鏈表),指向第一個需要指向的任務 
 //所有的線程都從任務鏈表中獲取任務 "共享資源" 
 struct task * task_list; 
  
 //線程池中有多個線程,每一個線程都有tid, 需要一個數組去保存tid 
 pthread_t * tids; //malloc()  
  
 //線程池中正在服役的線程數,當前線程個數 
 unsigned int active_threads; 
  
 //線程池任務隊列最大的任務數量 
 unsigned int max_waiting_tasks; 
  
 //線程池任務隊列上當前有多少個任務 
 unsigned int cur_waiting_tasks; 
  
 //...... 
 
}; 
 
/* 
 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

上述就是小編為大家分享的如何分析Linux 下線程池的使用了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

准格尔旗| 平乐县| 佛坪县| 苏尼特右旗| 万安县| 榕江县| 六枝特区| 博白县| 日喀则市| 昭通市| 云霄县| 淮安市| 西丰县| 思南县| 临朐县| 建湖县| 定结县| 白城市| 乐亭县| 三门峡市| 遵化市| 万州区| 杭锦后旗| 南漳县| 襄樊市| 永川市| 随州市| 从江县| 文昌市| 竹溪县| 兴国县| 隆尧县| 河北省| 台江县| 万州区| 宣威市| 嘉禾县| 临城县| 陕西省| 六枝特区| 克东县|