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

歡迎訪問(wèn) 生活随笔!

生活随笔

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

linux

linux进程池 自动增长,linux下C 线程池的原理讲解和代码实现(能自行伸缩扩展线程数)...

發(fā)布時(shí)間:2025/3/15 linux 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux进程池 自动增长,linux下C 线程池的原理讲解和代码实现(能自行伸缩扩展线程数)... 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

什么線程池,為什么要使用線程池?下面是一個(gè)比喻。

階段一、一個(gè)醫(yī)院,每天面對(duì)成千上萬(wàn)的病人,處理方式是:來(lái)一個(gè)病人找來(lái)一個(gè)醫(yī)生處理,處理完了醫(yī)生也走了。當(dāng)看病時(shí)間較短的時(shí)候,醫(yī)生來(lái)去的時(shí)間,顯得尤為費(fèi)時(shí)了。

階段二、醫(yī)院引進(jìn)了線程池的概念。設(shè)置門(mén)診,把醫(yī)生全派出去坐診,病人來(lái)看病先掛號(hào)排隊(duì),醫(yī)生根據(jù)病人隊(duì)列順序依次處理各個(gè)病人,這樣就省去醫(yī)生來(lái)來(lái)去去的時(shí)間了。但是,很多時(shí)候病人不多,醫(yī)生卻很多導(dǎo)致很多醫(yī)生空閑浪費(fèi)水電資源撒。

階段三、醫(yī)院引進(jìn)了可伸縮性線程池的概念,如階段二,但是門(mén)診一開(kāi)始只派出了部分醫(yī)生,但是增加了一個(gè)領(lǐng)導(dǎo),病人依舊是排隊(duì)看病,領(lǐng)導(dǎo)負(fù)責(zé)協(xié)調(diào)整個(gè)醫(yī)院的醫(yī)生。當(dāng)病人很多醫(yī)生忙不過(guò)來(lái)的時(shí)候,領(lǐng)導(dǎo)就去多叫幾個(gè)醫(yī)生來(lái)幫忙;當(dāng)病人不多醫(yī)生太多的時(shí)候,領(lǐng)導(dǎo)就叫一些醫(yī)生回家休息去免得浪費(fèi)醫(yī)院資源。

階段三就是一個(gè)線程池的例子。

線程池包括:n個(gè)執(zhí)行任務(wù)的線程,一個(gè)任務(wù)隊(duì)列,一個(gè)管理線程

1、預(yù)先啟動(dòng)一些線程,線程負(fù)責(zé)執(zhí)行任務(wù)隊(duì)列中的任務(wù),當(dāng)隊(duì)列空時(shí),線程掛起。

2、調(diào)用的時(shí)候,直接往任務(wù)隊(duì)列添加任務(wù),并發(fā)信號(hào)通知線程隊(duì)列非空。

3、管理線程負(fù)責(zé)監(jiān)控任務(wù)隊(duì)列和系統(tǒng)中的線程狀態(tài),當(dāng)任務(wù)隊(duì)列為空,線程數(shù)目多且很多處于空閑的時(shí)候,便通知一些線程退出以節(jié)約系統(tǒng)資源;當(dāng)任務(wù)隊(duì)列排隊(duì)任務(wù)多且線程都在忙,便負(fù)責(zé)再多啟動(dòng)一些線程來(lái)執(zhí)行任務(wù),以確保任務(wù)執(zhí)行效率。

下面是代碼(下載附件):運(yùn)行環(huán)境Ubuntu 12.04

#include

#include

#include

#include

#include

#include

#include

#include

#include "threadpool.h"

#define DEFAULT_TIME 10 // 領(lǐng)導(dǎo)定時(shí)檢查隊(duì)列、線程狀態(tài)的時(shí)間間隔

#define MIN_WAIT_TASK_NUM 10 // 隊(duì)列中等待的任務(wù)數(shù)>這個(gè)值,便會(huì)增加線程

#define DEFAULT_THREAD_VARY 10 //每次線程加減的數(shù)目

typedef struct

{

void *(*function)(void *);

void *arg;

} threadpool_task_t;

struct threadpool_t

{

pthread_mutex_t lock;// mutex for the taskpool

pthread_mutex_t thread_counter;//mutex for count the busy thread

pthread_cond_t queue_not_full;

pthread_cond_t queue_not_empty;//任務(wù)隊(duì)列非空的信號(hào)

pthread_t *threads;//執(zhí)行任務(wù)的線程

pthread_t adjust_tid;//負(fù)責(zé)管理線程數(shù)目的線程

threadpool_task_t *task_queue;//任務(wù)隊(duì)列

int min_thr_num;

int max_thr_num;

int live_thr_num;

int busy_thr_num;

int wait_exit_thr_num;

int queue_front;

int queue_rear;

int queue_size;

int queue_max_size;

bool shutdown;

};

/**

* @function void *threadpool_thread(void *threadpool)

* @desc the worker thread

* @param threadpool the pool which own the thread

*/

void *threadpool_thread(void *threadpool);

/**

* @function void *adjust_thread(void *threadpool);

* @desc manager thread

* @param threadpool the threadpool

*/

void *adjust_thread(void *threadpool);

/**

* check a thread is alive

*/

bool is_thread_alive(pthread_t tid);

int threadpool_free(threadpool_t *pool);

//創(chuàng)建線程池

threadpool_t *threadpool_create(int min_thr_num, int max_thr_num, int queue_max_size)

{

threadpool_t *pool = NULL;

do{

if((pool = (threadpool_t *)malloc(sizeof(threadpool_t))) == NULL)

{

printf("malloc threadpool fail");

break;

}

pool->min_thr_num = min_thr_num;

pool->max_thr_num = max_thr_num;

pool->busy_thr_num = 0;

pool->live_thr_num = min_thr_num;

pool->queue_size = 0;

pool->queue_max_size = queue_max_size;

pool->queue_front = 0;

pool->queue_rear = 0;

pool->shutdown = false;

pool->threads = (pthread_t *)malloc(sizeof(pthread_t)*max_thr_num);

if (pool->threads == NULL)

{

printf("malloc threads fail");

break;

}

memset(pool->threads, 0, sizeof(pool->threads));

pool->task_queue = (threadpool_task_t *)malloc(sizeof(threadpool_task_t)*queue_max_size);

if (pool->task_queue == NULL)

{

printf("malloc task_queue fail");

break;

}

if (pthread_mutex_init(&(pool->lock), NULL) != 0

|| pthread_mutex_init(&(pool->thread_counter), NULL) != 0

|| pthread_cond_init(&(pool->queue_not_empty), NULL) != 0

|| pthread_cond_init(&(pool->queue_not_full), NULL) != 0)

{

printf("init the lock or cond fail");

break;

}

/**

* start work thread min_thr_num

*/

for (int i = 0; i < min_thr_num; i++)

{

//啟動(dòng)任務(wù)線程

pthread_create(&(pool->threads[i]), NULL, threadpool_thread, (void *)pool);

printf("start thread 0x%x...\n", pool->threads[i]);

}

//啟動(dòng)管理線程

pthread_create(&(pool->adjust_tid), NULL, adjust_thread, (void *)pool);

return pool;

}while(0);

threadpool_free(pool);

return NULL;

}

//把任務(wù)添加到隊(duì)列中

int threadpool_add(threadpool_t *pool, void*(*function)(void *arg), void *arg)

{

assert(pool != NULL);

assert(function != NULL);

assert(arg != NULL);

pthread_mutex_lock(&(pool->lock));

//隊(duì)列滿的時(shí)候,等待

while ((pool->queue_size == pool->queue_max_size) && (!pool->shutdown))

{

//queue full wait

pthread_cond_wait(&(pool->queue_not_full), &(pool->lock));

}

if (pool->shutdown)

{

pthread_mutex_unlock(&(pool->lock));

}

//如下是添加任務(wù)到隊(duì)列,使用循環(huán)隊(duì)列

if (pool->task_queue[pool->queue_rear].arg != NULL)

{

free(pool->task_queue[pool->queue_rear].arg);

pool->task_queue[pool->queue_rear].arg = NULL;

}

pool->task_queue[pool->queue_rear].function = function;

pool->task_queue[pool->queue_rear].arg = arg;

pool->queue_rear = (pool->queue_rear + 1)%pool->queue_max_size;

pool->queue_size++;

//每次加完任務(wù),發(fā)個(gè)信號(hào)給線程

//若沒(méi)有線程處于等待狀態(tài),此句則無(wú)效,但不影響

pthread_cond_signal(&(pool->queue_not_empty));

pthread_mutex_unlock(&(pool->lock));

return 0;

}

//線程執(zhí)行任務(wù)

void *threadpool_thread(void *threadpool)

{

threadpool_t *pool = (threadpool_t *)threadpool;

threadpool_task_t task;

while(true)

{

/* Lock must be taken to wait on conditional variable */

pthread_mutex_lock(&(pool->lock));

//任務(wù)隊(duì)列為空的時(shí)候,等待

while ((pool->queue_size == 0) && (!pool->shutdown))

{

printf("thread 0x%x is waiting\n", pthread_self());

pthread_cond_wait(&(pool->queue_not_empty), &(pool->lock));

//被喚醒后,判斷是否是要退出的線程

if (pool->wait_exit_thr_num > 0)

{

pool->wait_exit_thr_num--;

if (pool->live_thr_num > pool->min_thr_num)

{

printf("thread 0x%x is exiting\n", pthread_self());

pool->live_thr_num--;

pthread_mutex_unlock(&(pool->lock));

pthread_exit(NULL);

}

}

}

if (pool->shutdown)

{

pthread_mutex_unlock(&(pool->lock));

printf("thread 0x%x is exiting\n", pthread_self());

pthread_exit(NULL);

}

//get a task from queue

task.function = pool->task_queue[pool->queue_front].function;

task.arg = pool->task_queue[pool->queue_front].arg;

pool->queue_front = (pool->queue_front + 1)%pool->queue_max_size;

pool->queue_size--;

//now queue must be not full

pthread_cond_broadcast(&(pool->queue_not_full));

pthread_mutex_unlock(&(pool->lock));

// Get to work

printf("thread 0x%x start working\n", pthread_self());

pthread_mutex_lock(&(pool->thread_counter));

pool->busy_thr_num++;

pthread_mutex_unlock(&(pool->thread_counter));

(*(task.function))(task.arg);

// task run over

printf("thread 0x%x end working\n", pthread_self());

pthread_mutex_lock(&(pool->thread_counter));

pool->busy_thr_num--;

pthread_mutex_unlock(&(pool->thread_counter));

}

pthread_exit(NULL);

return (NULL);

}

//管理線程

void *adjust_thread(void *threadpool)

{

threadpool_t *pool = (threadpool_t *)threadpool;

while (!pool->shutdown)

{

sleep(DEFAULT_TIME);

pthread_mutex_lock(&(pool->lock));

int queue_size = pool->queue_size;

int live_thr_num = pool->live_thr_num;

pthread_mutex_unlock(&(pool->lock));

pthread_mutex_lock(&(pool->thread_counter));

int busy_thr_num = pool->busy_thr_num;

pthread_mutex_unlock(&(pool->thread_counter));

//任務(wù)多線程少,增加線程

if (queue_size >= MIN_WAIT_TASK_NUM

&& live_thr_num < pool->max_thr_num)

{

//need add thread

pthread_mutex_lock(&(pool->lock));

int add = 0;

for (int i = 0; i < pool->max_thr_num && add < DEFAULT_THREAD_VARY

&& pool->live_thr_num < pool->max_thr_num; i++)

{

if (pool->threads[i] == 0 || !is_thread_alive(pool->threads[i]))

{

pthread_create(&(pool->threads[i]), NULL, threadpool_thread, (void *)pool);

add++;

pool->live_thr_num++;

}

}

pthread_mutex_unlock(&(pool->lock));

}

//任務(wù)少線程多,減少線程

if ((busy_thr_num * 2) < live_thr_num

&& live_thr_num > pool->min_thr_num)

{

//need del thread

pthread_mutex_lock(&(pool->lock));

pool->wait_exit_thr_num = DEFAULT_THREAD_VARY;

pthread_mutex_unlock(&(pool->lock));

//wake up thread to exit

for (int i = 0; i < DEFAULT_THREAD_VARY; i++)

{

pthread_cond_signal(&(pool->queue_not_empty));

}

}

}

}

int threadpool_destroy(threadpool_t *pool)

{

if (pool == NULL)

{

return -1;

}

pool->shutdown = true;

//adjust_tid exit first

pthread_join(pool->adjust_tid, NULL);

// wake up the waiting thread

pthread_cond_broadcast(&(pool->queue_not_empty));

for (int i = 0; i < pool->min_thr_num; i++)

{

pthread_join(pool->threads[i], NULL);

}

threadpool_free(pool);

return 0;

}

int threadpool_free(threadpool_t *pool)

{

if (pool == NULL)

{

return -1;

}

if (pool->task_queue)

{

free(pool->task_queue);

}

if (pool->threads)

{

free(pool->threads);

pthread_mutex_lock(&(pool->lock));

pthread_mutex_destroy(&(pool->lock));

pthread_mutex_lock(&(pool->thread_counter));

pthread_mutex_destroy(&(pool->thread_counter));

pthread_cond_destroy(&(pool->queue_not_empty));

pthread_cond_destroy(&(pool->queue_not_full));

}

free(pool);

pool = NULL;

return 0;

}

int threadpool_all_threadnum(threadpool_t *pool)

{

int all_threadnum = -1;

pthread_mutex_lock(&(pool->lock));

all_threadnum = pool->live_thr_num;

pthread_mutex_unlock(&(pool->lock));

return all_threadnum;

}

int threadpool_busy_threadnum(threadpool_t *pool)

{

int busy_threadnum = -1;

pthread_mutex_lock(&(pool->thread_counter));

busy_threadnum = pool->busy_thr_num;

pthread_mutex_unlock(&(pool->thread_counter));

return busy_threadnum;

}

bool is_thread_alive(pthread_t tid)

{

int kill_rc = pthread_kill(tid, 0);

if (kill_rc == ESRCH)

{

return false;

}

return true;

}

// for test

//void *process(void *arg)

//{

//printf("thread 0x%x working on task %d\n ",pthread_self(),*(int *)arg);

//sleep(1);

//printf("task %d is end\n",*(int *)arg);

//return NULL;

//}

//int main()

//{

//threadpool_t *thp = threadpool_create(3,100,12);

//printf("pool inited");

//

//int *num = (int *)malloc(sizeof(int)*20);

//for (int i=0;i<10;i++)

//{

//num[i]=i;

//printf("add task %d\n",i);

//threadpool_add(thp,process,(void*)&num[i]);

//}

//sleep(10);

//threadpool_destroy(thp);

//}

總結(jié)

以上是生活随笔為你收集整理的linux进程池 自动增长,linux下C 线程池的原理讲解和代码实现(能自行伸缩扩展线程数)...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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

主站蜘蛛池模板: 免费无遮挡无码永久视频 | 欧美男优| 无码不卡av东京热毛片 | 精品裸体舞一区二区三区 | 91手机视频| 午夜激情亚洲 | 成人性生交大片免费卡看 | 激情黄色小说视频 | 变态另类一区 | 久久嫩草精品久久久久 | 天天干夜夜拍 | 国产日产亚洲精品 | 亚洲男人第一天堂 | 欧美精品黑人 | 日韩资源在线观看 | 国产91在线精品 | 精品欧美久久 | 超碰在线98 | 无遮挡国产 | 视频一区二区三区在线观看 | 欧美成人精品一区二区男人小说 | 亚洲精品在线观看免费 | 日韩精品一区二区在线观看 | 精品一区二区久久久久久久网站 | 高级家教课程在线观看 | 男人午夜免费视频 | 亚洲专区免费 | 网站av在线 | 香蕉视频免费看 | 久久久久国产一区二区三区 | 给我看高清的视频在线观看 | 日本a v网站 | wwwxxx黄色片 | 国产精品无码av在线有声小说 | 91黑丝在线观看 | 午夜视频在线免费观看 | 91美女精品 | 亚洲精品中文字幕在线 | 欧美综合专区 | xxx69美国 | 2022av视频| 精品国产系列 | 日韩一区二区三区视频 | 国产欧美在线播放 | 欧美性久久久 | 男女互操 | 美女搞黄在线观看 | 成人高清视频免费观看 | 人妻熟女一区二区aⅴ水 | 日韩午夜精品视频 | 影音先锋国产精品 | 日韩国产欧美一区 | 成人黄色激情视频 | 97综合 | 91偷拍视频| 非洲黑人狂躁日本妞 | 亚洲日本精品一区 | 国产成年人 | 黄色综合网站 | 沟厕沟厕近拍高清视频 | 台湾av在线播放 | 日韩一级色 | 国产精品久久久午夜夜伦鲁鲁 | 海角社区在线视频播放观看 | 成人午夜淫片免费观看 | 中文文字幕文字幕高清 | 91蝌蚪91密月 | 色综合久久88色综合天天 | 2025韩国大尺度电影 | 免费无码av片在线观看 | 午夜精品久久久久久久99黑人 | 五月婷婷色综合 | 在线观看亚洲大片短视频 | 国产精品久久久久久妇女 | 东京热av一区 | 欧美日b片| 91在线视频国产 | 青青草视频 | 日批小视频 | 日本欧美不卡 | 免费一级特黄特色大片 | 午夜精品成人毛片非洲 | 伊甸园精品区 | 欧美日韩国产电影 | 黑人一级黄色片 | 后入内射无码人妻一区 | 小妹色播影院 | 久久久久中文字幕亚洲精品 | 无码视频一区二区三区 | 女同亚洲精品一区二区三 | 波多野结衣国产 | 激情777| a在线免费| 少妇全黄性生交片 | 日韩av片在线播放 | 超碰国产一区二区三区 | 亚州av综合色区无码一区 | 欧美日韩在线一区二区三区 | 大学生一级片 |