日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux系统编程——线程池

發(fā)布時間:2023/11/30 linux 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux系统编程——线程池 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

http://blog.csdn.net/tennysonsky/article/details/46490099#

線程池基本原理

在傳統(tǒng)服務(wù)器結(jié)構(gòu)中,常是有一個總的監(jiān)聽線程監(jiān)聽有沒有新的用戶連接服務(wù)器,每當(dāng)有一個新的用戶進(jìn)入,服務(wù)器就開啟一個新的線程用戶處理這 個用戶的數(shù)據(jù)包。這個線程只服務(wù)于這個用戶,當(dāng)用戶與服務(wù)器端關(guān)閉連接以后,服務(wù)器端銷毀這個線程。(關(guān)于并發(fā)服務(wù)器更多詳情,請看《并發(fā)服務(wù)器》)。


然而頻繁地開辟與銷毀線程極大地占用了系統(tǒng)的資源,而且在大量用戶的情況下,系統(tǒng)為了開辟和銷毀線程將浪費大量的時間和資源。線程池提供了一個解決外部大量用戶與服務(wù)器有限資源的矛盾。


線程池和傳統(tǒng)的一個用戶對應(yīng)一個線程的處理方法不同,它的基本思想就是在程序開始時就在內(nèi)存中開辟一些線程,線程的數(shù)目是固定的,他們獨自形成一個類,屏蔽了對外的操作,而服務(wù)器只需要將數(shù)據(jù)包交給線程池就可以了。當(dāng)有新的客戶請求到達(dá)時,不是新創(chuàng)建一個線程為其服務(wù),而是從“池子”中選擇一個空閑的線程為新的客戶請求服務(wù),服務(wù)完畢后,線程進(jìn)入空閑線程池中。如果沒有線程空閑的話,就將數(shù)據(jù)包暫時積累, 等待線程池內(nèi)有線程空閑以后再進(jìn)行處理。通過對多個任務(wù)重用已經(jīng)存在的線程對象,降低了對線程對象創(chuàng)建和銷毀的開銷。當(dāng)客戶請求 時,線程對象已經(jīng)存在,可以提高請求的響應(yīng)時間,從而整體地提高了系統(tǒng)服務(wù)的表現(xiàn)。


線程池應(yīng)用實例

一般來說實現(xiàn)一個線程池主要包括以下幾個組成部分:

1)線程管理器:用于創(chuàng)建并管理線程池。


2)工作線程:線程池中實際執(zhí)行任務(wù)的線程。在初始化線程時會預(yù)先創(chuàng)建好固定數(shù)目的線程在池中,這些初始化的線程一般處于空閑狀態(tài),一般不占用 CPU,占用較小的內(nèi)存空間。


3)任務(wù)接口:每個任務(wù)必須實現(xiàn)的接口,當(dāng)線程池的任務(wù)隊列中有可執(zhí)行任務(wù)時,被空閑的工作線程調(diào)去執(zhí)行(線程的閑與忙是通過互斥量實現(xiàn)的),把任務(wù)抽象出來形成接口,可以做到線程池與具體的任務(wù)無關(guān)。


4)任務(wù)隊列:用來存放沒有處理的任務(wù),提供一種緩沖機(jī)制,實現(xiàn)這種結(jié)構(gòu)有好幾種方法,常用的是隊列,主要運用先進(jìn)先出原理,另外一種是鏈表之類的數(shù)據(jù)結(jié)構(gòu),可以動態(tài)的為它分配內(nèi)存空間,應(yīng)用中比較靈活,此教程就是用到的鏈表。


什么時候需要創(chuàng)建線程池呢?簡單的說,如果一個應(yīng)用需要頻繁的創(chuàng)建和銷毀線程,而任務(wù)執(zhí)行的時間又非常短,這樣線程創(chuàng)建和銷毀的帶來的開銷就不容忽視,這時也是線程池該出場的機(jī)會了。如果線程創(chuàng)建和銷毀時間相比任務(wù)執(zhí)行時間可以忽略不計,則沒有必要使用線程池了。


線程池實現(xiàn)示例代碼如下:


thread_pool.h 的示例代碼:

[cpp]?view plaincopy
  • #ifndef?__THREAD_POOL_H__??
  • #define?__THREAD_POOL_H__??
  • ??
  • #include?<pthread.h>??
  • ??
  • ?/*********************************************************************?
  • *?任務(wù)回調(diào)函數(shù),也可根據(jù)需要自行修改?
  • *********************************************************************/??
  • typedef?void?*(*pool_task_f)(void?*arg);??
  • ??
  • /*********************************************************************?
  • *?任務(wù)句柄?
  • *********************************************************************/??
  • typedef?struct?_task{??
  • ????pool_task_f?process;/*回調(diào)函數(shù),任務(wù)運行時會調(diào)用此函數(shù),注意也可聲明成其它形式*/??
  • ????void?*arg;?????/*回調(diào)函數(shù)的參數(shù)*/??
  • ????struct?_task?*next;??
  • }pool_task;??
  • ??
  • /*********************************************************************?
  • *?線程池句柄?
  • *********************************************************************/??
  • typedef?struct??
  • {??
  • ????pthread_t?*threadid;????????/*?線程號?*/??
  • ????int?threads_limit;??????????/*?線程池中允許的活動線程數(shù)目?*/??
  • ????int?destroy_flag;???????????/*?是否銷毀線程池?,?0銷毀,1不銷毀*/??
  • ????pool_task?*queue_head;??????/*?鏈表結(jié)構(gòu),線程池中所有等待任務(wù)?*/??
  • ????int?task_in_queue;??????????/*?當(dāng)前等待隊列的任務(wù)數(shù)目?*/??
  • ????pthread_mutex_t?queue_lock;?/*?鎖?*/??
  • ????pthread_cond_t?queue_ready;?/*?條件變量?*/??
  • }pool_t;??
  • ??
  • /*********************************************************************?
  • *功能:????????初始化線程池結(jié)構(gòu)體并創(chuàng)建線程?
  • *參數(shù):?????????
  • ????????????pool:線程池句柄?
  • ????????????threads_limit:線程池中線程的數(shù)量?
  • *返回值:???無?
  • *********************************************************************/??
  • void?pool_init(pool_t?*pool,?int?threads_limit);??
  • ??
  • /*********************************************************************?
  • *功能:????????銷毀線程池,等待隊列中的任務(wù)不會再被執(zhí)行,?
  • ????????????但是正在運行的線程會一直,把任務(wù)運行完后再退出?
  • *參數(shù):????????線程池句柄?
  • *返回值:???成功:0,失敗非0?
  • *********************************************************************/??
  • int?pool_uninit(pool_t?*pool);??
  • ??
  • /*********************************************************************?
  • *功能:????????向線程池中添加一個任務(wù)?
  • *參數(shù):?????????
  • ????????????pool:線程池句柄?
  • ????????????process:任務(wù)處理函數(shù)?
  • ????????????arg:任務(wù)參數(shù)?
  • *返回值:???0?
  • *********************************************************************/??
  • int?pool_add_task(pool_t?*pool,?pool_task_f?process,?void?*arg);??
  • ??
  • ??
  • #endif??

  • thread_pool.c 的示例代碼:
    [cpp]?view plaincopy
  • #include?<stdio.h>??
  • #include?<stdlib.h>??
  • #include?<pthread.h>??
  • #include?<assert.h>??
  • ??
  • #include?"thread_pool.h"??
  • ??
  • static?void?*pool_thread_server(void?*arg);??
  • ??
  • /*********************************************************************?
  • *功能:????????初始化線程池結(jié)構(gòu)體并創(chuàng)建線程?
  • *參數(shù):?????????
  • ????????????pool:線程池句柄?
  • ????????????threads_limit:線程池中線程的數(shù)量?
  • *返回值:???無?
  • *********************************************************************/??
  • void?pool_init(pool_t?*pool,?int?threads_limit)??
  • {??
  • ????pool->threads_limit?=?threads_limit;??
  • ????pool->queue_head?=?NULL;??
  • ????pool->task_in_queue?=?0;??
  • ????pool->destroy_flag?=?0;??
  • ????/*創(chuàng)建存放線程ID的空間*/??
  • ????pool->threadid?=?(pthread_t?*)calloc(threads_limit,?sizeof(pthread_t));??
  • ????int?i?=?0;??
  • ????/*初始化互斥鎖和條件變量*/??
  • ????pthread_mutex_init(&(pool->queue_lock),?NULL);??
  • ????pthread_cond_init(&(pool->queue_ready),?NULL);??
  • ????/*循環(huán)創(chuàng)建threads_limit個線程*/??
  • ????for?(i?=?0;?i?<?threads_limit;?i++){??
  • ????????pthread_create(&(pool->threadid[i]),?NULL,?pool_thread_server,?pool);??
  • ????}??
  • ????return;??
  • }??
  • ??
  • /*********************************************************************?
  • *功能:????????銷毀線程池,等待隊列中的任務(wù)不會再被執(zhí)行,?
  • ????????????但是正在運行的線程會一直,把任務(wù)運行完后再退出?
  • *參數(shù):????????線程池句柄?
  • *返回值:???成功:0,失敗非0?
  • *********************************************************************/??
  • int?pool_uninit(pool_t?*pool)??
  • {??
  • ????pool_task?*head?=?NULL;??
  • ????int?i;??
  • ??????
  • ????pthread_mutex_lock(&(pool->queue_lock));??
  • ????if(pool->destroy_flag)/*?防止兩次調(diào)用?*/??
  • ????????return?-1;??
  • ????pool->destroy_flag?=?1;??
  • ????pthread_mutex_unlock(&(pool->queue_lock));??
  • ????/*?喚醒所有等待線程,線程池要銷毀了?*/??
  • ????pthread_cond_broadcast(&(pool->queue_ready));??
  • ????/*?阻塞等待線程退出,否則就成僵尸了?*/??
  • ????for?(i?=?0;?i?<?pool->threads_limit;?i++)??
  • ????????pthread_join(pool->threadid[i],?NULL);??
  • ????free(pool->threadid);??
  • ????/*?銷毀等待隊列?*/??
  • ????pthread_mutex_lock(&(pool->queue_lock));??
  • ????while(pool->queue_head?!=?NULL){??
  • ????????head?=?pool->queue_head;??
  • ????????pool->queue_head?=?pool->queue_head->next;??
  • ????????free(head);??
  • ????}??
  • ????pthread_mutex_unlock(&(pool->queue_lock));??
  • ????/*條件變量和互斥量也別忘了銷毀*/??
  • ????pthread_mutex_destroy(&(pool->queue_lock));??
  • ????pthread_cond_destroy(&(pool->queue_ready));??
  • ????return?0;??
  • }??
  • ??
  • /*********************************************************************?
  • *功能:????????向任務(wù)隊列中添加一個任務(wù)?
  • *參數(shù):?????????
  • ????????????pool:線程池句柄?
  • ????????????process:任務(wù)處理函數(shù)?
  • ????????????arg:任務(wù)參數(shù)?
  • *返回值:???無?
  • *********************************************************************/??
  • static?void?enqueue_task(pool_t?*pool,?pool_task_f?process,?void?*arg)??
  • {??
  • ????pool_task?*task?=?NULL;??
  • ????pool_task?*member?=?NULL;??
  • ??????
  • ????pthread_mutex_lock(&(pool->queue_lock));??
  • ??????
  • ????if(pool->task_in_queue?>=?pool->threads_limit){??
  • ????????printf("task_in_queue?>?threads_limit!\n");??
  • ????????pthread_mutex_unlock?(&(pool->queue_lock));??
  • ????????return;??
  • ????}??
  • ??????
  • ????task?=?(pool_task?*)calloc(1,?sizeof(pool_task));??
  • ????assert(task?!=?NULL);??
  • ????task->process?=?process;??
  • ????task->arg?=?arg;??
  • ????task->next?=?NULL;??
  • ????pool->task_in_queue++;??
  • ????member?=?pool->queue_head;??
  • ????if(member?!=?NULL){??
  • ????????while(member->next?!=?NULL)??/*?將任務(wù)加入到任務(wù)鏈連的最后位置.?*/??
  • ????????????member?=?member->next;??
  • ????????member->next?=?task;??
  • ????}else{??
  • ????????pool->queue_head?=?task;?/*?如果是第一個任務(wù)的話,就指向頭?*/??
  • ????}??
  • ????printf("\ttasks?%d\n",?pool->task_in_queue);??
  • ????/*?等待隊列中有任務(wù)了,喚醒一個等待線程?*/??
  • ????pthread_cond_signal?(&(pool->queue_ready));??
  • ????pthread_mutex_unlock?(&(pool->queue_lock));??
  • }??
  • ??
  • /*********************************************************************?
  • *功能:????????從任務(wù)隊列中取出一個任務(wù)?
  • *參數(shù):????????線程池句柄?
  • *返回值:???任務(wù)句柄?
  • *********************************************************************/??
  • static?pool_task?*dequeue_task(pool_t?*pool)??
  • {??
  • ????pool_task?*task?=?NULL;??
  • ??????
  • ????pthread_mutex_lock(&(pool->queue_lock));??
  • ????/*?判斷線程池是否要銷毀了?*/??
  • ????if(pool->destroy_flag){??
  • ????????pthread_mutex_unlock(&(pool->queue_lock));??
  • ????????printf("thread?0x%lx?will?be?destroyed\n",?pthread_self());??
  • ????????pthread_exit(NULL);??
  • ????}??
  • ????/*?如果等待隊列為0并且不銷毀線程池,則處于阻塞狀態(tài)?*/??
  • ????if(pool->task_in_queue?==?0){??
  • ????????while((pool->task_in_queue?==?0)?&&?(!pool->destroy_flag)){??
  • ????????????printf("thread?0x%lx?is?waitting\n",?pthread_self());??
  • ????????????/*?注意:pthread_cond_wait是一個原子操作,等待前會解鎖,喚醒后會加鎖?*/??
  • ????????????pthread_cond_wait(&(pool->queue_ready),?&(pool->queue_lock));??
  • ????????}??
  • ????}else{??
  • ????????/*?等待隊列長度減去1,并取出隊列中的第一個元素?*/??
  • ????????pool->task_in_queue--;??
  • ????????task?=?pool->queue_head;??
  • ????????pool->queue_head?=?task->next;??
  • ????????printf("thread?0x%lx?received?a?task\n",?pthread_self());??
  • ????}??
  • ????pthread_mutex_unlock(&(pool->queue_lock));??
  • ????return?task;??
  • }??
  • ??
  • /*********************************************************************?
  • *功能:????????向線程池中添加一個任務(wù)?
  • *參數(shù):?????????
  • ????????????pool:線程池句柄?
  • ????????????process:任務(wù)處理函數(shù)?
  • ????????????arg:任務(wù)參數(shù)?
  • *返回值:???0?
  • *********************************************************************/??
  • int?pool_add_task(pool_t?*pool,?pool_task_f?process,?void?*arg)??
  • {??
  • ????enqueue_task(pool,?process,?arg);??
  • ????return?0;??
  • }??
  • ??
  • /*********************************************************************?
  • *功能:????????線程池服務(wù)程序?
  • *參數(shù):????????略?
  • *返回值:???略?
  • *********************************************************************/??
  • static?void?*pool_thread_server(void?*arg)??
  • {??
  • ????pool_t?*pool?=?NULL;??
  • ??????
  • ????pool?=?(pool_t?*)arg;??
  • ????while(1){??
  • ????????pool_task?*task?=?NULL;??
  • ????????task?=?dequeue_task(pool);??
  • ????????/*調(diào)用回調(diào)函數(shù),執(zhí)行任務(wù)*/??
  • ????????if(task?!=?NULL){??
  • ????????????printf?("thread?0x%lx?is?busy\n",?pthread_self());??
  • ????????????task->process(task->arg);??
  • ????????????free(task);??
  • ????????????task?=?NULL;??
  • ????????}??
  • ????}??
  • ????/*這一句應(yīng)該是不可達(dá)的*/??
  • ????pthread_exit(NULL);????
  • ????return?NULL;??
  • }??

  • 下面是測試代碼:

    [cpp]?view plaincopy
  • #include?<stdio.h>??
  • #include?<unistd.h>??
  • ??
  • #include?"thread_pool.h"??
  • ??
  • void?*task_test(void?*arg)??
  • {??
  • ????printf("\t\tworking?on?task?%d\n",?(int)arg);??
  • ????sleep(1);???????????/*休息一秒,延長任務(wù)的執(zhí)行時間*/??
  • ????return?NULL;??
  • }??
  • ??
  • void?thread_pool_demo(void)??
  • {??
  • ????pool_t?pool;??
  • ????int?i?=?0;??
  • ??
  • ????pool_init(&pool,?2);//初始化一個線程池,其中創(chuàng)建2個線程??
  • ????sleep(1);??
  • ????for(i?=?0;?i?<?5;?i++){??
  • ????????sleep(1);??
  • ????????pool_add_task(&pool,?task_test,?(void?*)i);//添加一個任務(wù)??
  • ????}??
  • ????sleep(4);??
  • ??
  • ????pool_uninit(&pool);//刪除線程池??
  • }??
  • ??
  • int?main?(int?argc,?char?*argv[])??
  • {????
  • ????thread_pool_demo();??
  • ????return?0;??
  • }??

  • 運行結(jié)果如下:




    本教程示例代碼下載請點此處。


    參考資料:http://blog.csdn.net/hubi0952


    總結(jié)

    以上是生活随笔為你收集整理的Linux系统编程——线程池的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。