博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux下的线程池
阅读量:6606 次
发布时间:2019-06-24

本文共 5253 字,大约阅读时间需要 17 分钟。

---恢复内容开始---

  1. 什么是线程池?

 

在系统如果只是有一个客户请求就去建立一个线程去处理请求会很麻烦,对于面向对象的创建的过程,创建和析构一个类浪费内存和时间。所以预先创建几个线程,对其进行管理。

  1. 线程池的应用方面

当某个网站需要大量点击时,工程量大

当有大量的客户端请求的时候,要求服务端响应的时间要短暂一些

对于性能有要求的时候

  1. 线程池的特点

1>经典生产者消费者模型。

2>线程池中有若干等待的线程。

3>线程池中的线程用于执行大量的相对短暂的任务。

4.线程池的功能描述

当任务增加时,可以动态增加线程池中线程的个数,

当任务执行完成后,可以动态的减少线程池中线程的个数。

生产者线程向任务队列中添加任务,任务队列中有任务,如果有等待线程就唤醒并执行任务

如果线程池中没有等待线程并且没有达到上限,就添加新的线程到线程池

5..线程池的创建思路

如上图所示:

在任务队列中进行为不为空和不为满判断------>用户程序阻塞,当不为满的时候,用户程序往队列中添加队列------>当不为空的时候,线程池中的线程从任务队列中取走任务------->线程调用封装好的线程执行函数去执行任务-------->线程池的线程执行完任务进行判断,如果超过预设的时间没有程序调用,则退出----->退出后进行程序的销毁

6.实例

#include 
#include
#include
#include
#include
#include
#include
//定义条件变量typedef struct condition{ pthread_mutex_t pmutex; pthread_cond_t pcond;}condition_t;//定义任务结构体typedef struct task{ void *(*run) (void *arg); void *arg; struct task *next;}task_t;//定义线程池结构体typedef struct threadpoll{ int count;//计数 int idle;//闲置 int max_threads;//最大线程 int quit;//退出 task_t *first; task_t *last; condition_t ready;}threadpoll_t;//初始化条件变量int condition_init(condition_t *cond){ int status; if(status=pthread_mutex_init(&cond->pmutex,NULL));//返回值是0则代表初始化成功 return status;//创出状态值 if(status=pthread_cond_init(&cond->pcond,NULL)); return status; return 0;}int condition_lock(condition_t *cond){ return pthread_mutex_lock(&cond->pmutex);}int condition_unlock(condition_t *cond){ return pthread_mutex_unlock(&cond->pmutex);}int condition_wait(condition_t *cond){ return pthread_cond_wait(&cond->pcond,&cond->pmutex);}int condition_timewait(condition_t *cond,const struct timespec* abstime){ return pthread_cond_timedwait(&cond->pcond,&cond->pmutex,abstime);}int condition_signal(condition_t *cond){ return pthread_cond_signal(&cond->pcond);}int condition_broadcast(condition_t *cond){ return pthread_cond_broadcast(&cond->pcond);}int condition_destory(condition_t *cond){ int status; if(status=pthread_mutex_destroy(&cond->pmutex));//返回值是0则代表初始化成功 return status;//创出状态值 if(status=pthread_cond_destory(&cond->pcond)); return status; return 0; }//工作线程void *thread_rountin(void *arg){ //等待时长 struct timespec abstime; int timeout; //打印线程ID printf("thread 0x%0x is starting\n",(int)pthread_self()); //用于接收结构体 threadpoll_t *poll = (threadpoll_t *)arg; //1、直接锁住 //2、队列已满,阻塞队列不为满上 //3、清空任务队列 //4、添加任务到任务队列里,队尾指针往后挪 //5、唤醒线程池,等待处理任务线程 while(1) { timeout=0; //上锁 condition_lock(&poll->ready); poll->idle++;//闲置线程++进行线程的闲置操作 while(poll -> first == NULL && !poll -> quit) { printf("thread 0x%0x is waiting\n",(int)pthread_self()); clock_gettime(CLOCK_REALTIME,&abstime); abstime.tv_sec += 2; int status=condition_timewait(&poll -> ready,&abstime); if(status == ETIMEDOUT) { printf("thread 0x%0x is wait timed out\n",(int)pthread_self()); timeout = 1; break; } } //等待队列有任务到来或者线程池销毁的通知 poll->idle--; //如果有任务 if(poll->first!=NULL) { //移动下标 task_t *t=poll->first; poll->first=t->next; //需要先解锁,以便添加新任务。其他消费者线程能够进入等待任务。 condition_unlock(&poll -> ready); t -> run(t->arg); free(t); condition_lock(&poll -> ready); } //等待线程销毁的通知 if(poll -> quit && poll ->first == NULL) { poll -> count--; if(poll->count == 0) { condition_signal(&poll -> ready); } condition_unlock(&poll->ready); //跳出循环之前要记得解锁 break; } if(timeout &&poll -> first ==NULL) { poll -> count--; condition_unlock(&poll->ready); //跳出循环之前要记得解锁 break; } condition_unlock(&poll -> ready); } printf("thread 0x%0x is exiting\n",(int)pthread_self()); return NULL;}//初始化线程池void poll_init(threadpoll_t *poll,int threads){ condition_init(&poll->ready); poll->first=NULL; poll->last=NULL; poll->count=0; poll->idle=0; poll->max_threads=threads; poll->quit=0; }//创建任务void pthrad_add_task(threadpoll_t *poll, void *(*run)(void *arg),void *arg){ //创建任务 添加任务 task_t *newtask=(task_t *)malloc(sizeof(task_t)); newtask->run=run; newtask->arg=arg; newtask->next=NULL; //上锁 condition_lock(&poll->ready); //添加任务到队列 if(poll->first==NULL) { poll->first=newtask; } else poll->last->next=newtask; poll->last=newtask; //如果有等待线程,则唤醒其中一个 if(poll -> idle > 0) { //如果没有闲置的的,则唤醒其中一个 condition_signal(&poll -> ready); } else if(poll -> count< poll -> max_threads) { //如果没有则创建工作线程 pthread_t tid; //执行回调 pthread_create(&tid,NULL,thread_rountin,poll); //忙线程加一 poll -> count++; } condition_unlock(&poll -> ready);}//销毁线程池void pthread_task_destory(threadpoll_t *poll){ if(poll->quit) { return; } condition_lock(&poll->ready); poll->quit = 1; if(poll -> count > 0) { if(poll -> idle > 0) condition_broadcast(&poll->ready); while(poll -> count > 0) { condition_wait(&poll->ready); } } condition_unlock(&poll->ready); condition_destory(&poll -> ready);}//回调函数void *mytask(void *arg){ printf("thread 0x%0x is working on task %d\n",(int)pthread_self(),*(int*)arg); sleep(1); free(arg); return NULL;} int main(){ //1、没有写socket 不然在300行也写不完,用简单的for循环模拟客户端生产的数据每个线程处理数据 //gcc main.c -o main -lpthread -lrt threadpoll_t pool; //创建线程池 poll_init(&pool,100); //模拟客户端领数据 int i ; for(i = 0; i < 100; i++) { int *arg = (int *)malloc(sizeof(int)); *arg = i; //向线程池添加任务 pthrad_add_task(&pool,mytask,arg); } //为了等待其他线程结束 当然也可以通过pthread_join来做 sleep(15); //线程销毁 pthread_task_destory(&pool); return 0; }

 

  运行结果如下:

当任务结束线程池的线程就会等待,当等待超过一定时间。就会退出。

 

---恢复内容结束---

转载于:https://www.cnblogs.com/ylq0824/p/10925081.html

你可能感兴趣的文章
常用sql经典语句
查看>>
009_作用域
查看>>
javascript事件处理
查看>>
GridView導出Excel 解決亂碼問題
查看>>
ios规格证明
查看>>
ASP.NET下的JQ上传
查看>>
Linux安装mysql5.7
查看>>
openstack 制作镜像以及windows向Linux中通过xshell传文件
查看>>
和算法导论没什么关系0.手电筒过桥问题详解
查看>>
第二周学习
查看>>
3.25阅读摘抄
查看>>
LeeCode-Swap Nodes in Pairs
查看>>
JSR303结合切面校验参数
查看>>
130242014076+陈旭+第2次实验
查看>>
【MySQL】centOS中安装和配置MySQL
查看>>
bzoj 1070: [SCOI2007]修车
查看>>
乱码发生的原因
查看>>
CMD命令行基本命令
查看>>
Go语言的通道(2)-缓冲通道
查看>>
javascript 正则表达式邮箱验证
查看>>