nginx線程池源碼是什么

  1.任務節點

typedef?void?(*cb_fun)(void?*);  //任務結構體 typedef?struct?task { ??void????*argv;?//任務函數的參數(任務執行結束前,要保證參數地址有效) ??cb_fun????handler;?//任務函數(返回值必須為0??非0值用作增加線程,和銷毀線程池) ??struct?task?*next;?//任務鏈指針 }zoey_task_t;

  handler為函數指針,是實際的任務函數,argv為該函數的參數,next指向下一個任務。

  2.任務隊列

typedef?struct?task_queue { ??zoey_task_t?*head;?//隊列頭 ??zoey_task_t?**tail;??//隊列尾 ??unsigned?int?maxtasknum;?//最大任務限制 ??unsigned?int?curtasknum;?//當前任務數 }zoey_task_queue_t;

  head為任務隊列頭指針,tail為任務隊列尾指針,maxtasknum為隊列最大任務數限制,curtasknum為隊列當前任務數。

  3.線程池

typedef?struct?threadpool { ??pthread_mutex_t??mutex;?//互斥鎖 ??pthread_cond_t???cond;??//條件鎖 ??zoey_task_queue_t????tasks;//任務隊列  ??unsigned?int????threadnum;?//線程數 ??unsigned?int????thread_stack_size;?//線程堆棧大小  }zoey_threadpool_t;

  mutex為互斥鎖 cond為條件鎖。mutex和cond共同保證線程池任務的互斥領取或者添加。

  tasks指向任務隊列。

  threadnum為線程池的線程數

  thread_stack_size為線程堆棧大小 

  4.啟動配置

//配置參數 typedef?struct?threadpool_conf { ??unsigned?int?threadnum;??//線程數 ??unsigned?int?thread_stack_size;//線程堆棧大小 ??unsigned?int?maxtasknum;//最大任務限制 }zoey_threadpool_conf_t;

  啟動配置結構體是初始化線程池時的一些參數。

  5.初始化線程池

  首先檢查參數是否合法,然后初始化mutex,cond,key(pthread_key_t)。key用來讀寫線程全局變量,此全局變量控制線程是否退出。

  最后創建線程。

zoey_threadpool_t*?zoey_threadpool_init(zoey_threadpool_conf_t?*conf) { ??zoey_threadpool_t?*pool?=?null; ??int?error_flag_mutex?=?0; ??int?error_flag_cond?=?0; ??pthread_attr_t?attr; ??do{ ????if?(z_conf_check(conf)?==?-1){?//檢查參數是否合法 ??????break; ????}  ????pool?=?(zoey_threadpool_t?*)malloc(sizeof(zoey_threadpool_t));//申請線程池句柄 ????if?(pool?==?null){ ??????break; ????}  ????//初始化線程池基本參數 ????pool->threadnum?=?conf->threadnum; ????pool->thread_stack_size?=?conf->thread_stack_size; ????pool->tasks.maxtasknum?=?conf->maxtasknum; ????pool->tasks.curtasknum?=?0;  ????z_task_queue_init(&pool->tasks); ?? ????if?(z_thread_key_create()?!=?0){//創建一個pthread_key_t,用以訪問線程全局變量。 ??????free(pool); ??????break; ????} ????if?(z_thread_mutex_create(&pool->mutex)?!=?0){?//初始化互斥鎖 ??????z_thread_key_destroy(); ??????free(pool); ??????break; ????}  ????if?(z_thread_cond_create(&pool->cond)?!=?0){?//初始化條件鎖 ??????z_thread_key_destroy(); ??????z_thread_mutex_destroy(&pool->mutex); ??????free(pool); ??????break; ????}  ????if?(z_threadpool_create(pool)?!=?0){????//創建線程池 ??????z_thread_key_destroy(); ??????z_thread_mutex_destroy(&pool->mutex); ??????z_thread_cond_destroy(&pool->cond); ??????free(pool); ??????break; ????} ????return?pool; ??}while(0);  ??return?null; }

 6.添加任務

  首先申請一個任務節點,實例化后將節點加入任務隊列,并將當前任務隊列數++并通知其他進程有新任務。整個過程加鎖。

int?zoey_threadpool_add_task(zoey_threadpool_t?*pool,?cb_fun?handler,?void*?argv) { ??zoey_task_t?*task?=?null; ??//申請一個任務節點并賦值 ??task?=?(zoey_task_t?*)malloc(sizeof(zoey_task_t)); ??if?(task?==?null){ ????return?-1; ??} ??task->handler?=?handler; ??task->argv?=?argv; ??task->next?=?null; ??if?(pthread_mutex_lock(&pool->mutex)?!=?0){?//加鎖 ????free(task); ????return?-1; ??} ??do{  ????if?(pool->tasks.curtasknum?>=?pool->tasks.maxtasknum){//判斷工作隊列中的任務數是否達到限制 ??????break; ????}  ????//將任務節點尾插到任務隊列 ????*(pool->tasks.tail)?=?task; ????pool->tasks.tail?=?&task->next; ????pool->tasks.curtasknum++;  ????//通知阻塞的線程 ????if?(pthread_cond_signal(&pool->cond)?!=?0){ ??????break; ????} ????//解鎖 ????pthread_mutex_unlock(&pool->mutex); ????return?0;  ??}while(0); ??pthread_mutex_unlock(&pool->mutex); ??free(task); ??return?-1;  }

 7.銷毀線程池

  銷毀線程池其實也是向任務隊列添加任務,只不過添加的任務是讓線程退出。z_threadpool_exit_cb函數會將lock置0后退出線程,lock為0表示此線程

  已經退出,接著退出下一個線程。退出完線程釋放所有資源。

void?zoey_threadpool_destroy(zoey_threadpool_t?*pool) { ??unsigned?int?n?=?0; ??volatile?unsigned?int?lock;  ??//z_threadpool_exit_cb函數會使對應線程退出 ??for?(;?n?threadnum;?n++){ ????lock?=?1; ????if?(zoey_threadpool_add_task(pool,?z_threadpool_exit_cb,?&lock)?!=?0){ ??????return; ????} ????while?(lock){ ??????usleep(1); ????} ??} ??z_thread_mutex_destroy(&pool->mutex); ??z_thread_cond_destroy(&pool->cond); ??z_thread_key_destroy(); ??free(pool); }

 8.增加一個線程

  很簡單,再生成一個線程以及線程數++即可。加鎖。

int?zoey_thread_add(zoey_threadpool_t?*pool) { ??int?ret?=?0; ??if?(pthread_mutex_lock(&pool->mutex)?!=?0){ ????return?-1; ??} ??ret?=?z_thread_add(pool); ??pthread_mutex_unlock(&pool->mutex); ??return?ret; }

 9.改變任務隊列最大任務限制

  當num=0時設置線程數為無限大。

void?zoey_set_max_tasknum(zoey_threadpool_t?*pool,unsigned?int?num) { ??if?(pthread_mutex_lock(&pool->mutex)?!=?0){ ????return?-1; ??} ??z_change_maxtask_num(pool,?num);?//改變最大任務限制 ??pthread_mutex_unlock(&pool->mutex); }

  10.使用示例

int?main() { ??int?array[10000]?=?{0}; ??int?i?=?0; ??zoey_threadpool_conf_t?conf?=?{5,0,5};?//實例化啟動參數 ??zoey_threadpool_t?*pool?=?zoey_threadpool_init(&conf);//初始化線程池 ??if?(pool?==?null){ ????return?0; ??} ??for?(;?i?

? 版權聲明
THE END
喜歡就支持一下吧
點贊14 分享