Linux C下实现线程池
下面是原文链接,我是照着敲的。。。hi.baidu.com/boahegcrmdghots/item/f3ca1a3c2d47fcc52e8ec2e1
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/types.h>
#include<pthread.h>
#include<assert.h>/*
线程池里所有运行和等待的任务都是一个thread_job
由于所有任务都在链表中,所以是一个链表结构
*/
typedef struct job
{/*回调函数,任务运行时会调用次函数,注意也可以声明为其他形式*/void * (*process)(void *arg);void *arg;struct job *next;
}thread_job;/*线程池结构*/
typedef struct
{pthread_mutex_t queue_lock;pthread_cond_t queue_ready;/*链表结构,线程池中所有等待任务*/thread_job *queue_head;/*线程池销毁标记*/int destroy;/**/pthread_t *threadid;/*线程池中允许的最大线程数目*/int max_thread_num;/*等待队列的任务数目*/int cur_queue_size;
}thread_pool;int add_job(void *(*process)(void *arg), void *arg);
void *thread_runtine(void *arg);/*把线程池指针设为静态*/
static thread_pool *pool = NULL;/*初始化线程池*/
void pool_init(int max_thread_num)
{pool = (thread_pool *)malloc(sizeof(thread_pool));pthread_mutex_init(&(pool->queue_lock), NULL);pthread_cond_init(&(pool->queue_ready), NULL);pool->queue_head = NULL;pool->max_thread_num = max_thread_num;pool->cur_queue_size = 0;/*为线程池中的各个线程分配空间 做初始化*/pool->threadid = (pthread_t *)malloc(max_thread_num*sizeof(pthread_t));int i = 0;/*创建max_thread_num个线程*/for(i=0; i<max_thread_num; i++){/*理解线程创建函数各个参数, 每个线程都会执行thread_runtine函数*/pthread_create(&(pool->threadid[i]), NULL, thread_runtine, NULL);}
}
/*每个线程都会执行runtine函数, 每个thread_rutine函数都是取出一个thread_job处理任务
也就是说,线程池中可能有很多个thread_job需要cur_queue_size个线程去处理,处理前要
先对线程池加锁,保证当前处理任务的线程处理thread_job时不会收到其他线程影响,能够互斥访问*/
void *thread_runtine(void *arg)
{printf("starting thread 0x%x\n", (unsigned int)pthread_self());while(1){/*对线程池加互斥锁*/pthread_mutex_lock(&(pool->queue_lock));/*如果线程当前的等待队列为0,并且没有被销毁,则处于阻塞状态pthread_cond_wait是一个原子操作,等待前解锁,唤醒后会加锁*/while( (pool->cur_queue_size == 0) && (!pool->destroy) ){printf("thread 0x%x is waiting\n", (unsigned int)pthread_self());pthread_cond_wait(&(pool->queue_ready), &(pool->queue_lock));}/*线程池销毁了*/if(pool->destroy){pthread_mutex_lock(&(pool->queue_lock));printf("thread 0x%x will exit\n", (unsigned int)pthread_self());pthread_exit(NULL);}printf("thread 0x%x is starting to work\n", (unsigned int)pthread_self());assert(pool->cur_queue_size != 0);assert(pool->queue_head != NULL);/*等待队列长度减1,并取出线程池中的线程链表中的头元素*/pool->cur_queue_size--;thread_job *job = pool->queue_head;pool->queue_head = job->next;pthread_mutex_unlock(&(pool->queue_lock));/*调用回调函数,执行任务, */(*(job->process))(job->arg);free(job);job = NULL;}/*这一句是不可达的*/pthread_exit(NULL);
}
/*向线程池中添加任务, 重点理解参数, 每个任务要做的事体现在process回调函数上*/
int pool_add_job(void *(*process)(void *arg), void *arg)
{thread_job *newjob = (thread_job *)malloc(sizeof(thread_job));newjob->process = process;newjob->arg = arg;newjob->next = NULL;/*对线程池加锁*/pthread_mutex_lock(&(pool->queue_lock));thread_job *member = pool->queue_head;if(member != NULL){while(member->next != NULL)member = member->next;member->next = newjob;}else{pool->queue_head = newjob;}assert(pool->queue_head != NULL);pool->cur_queue_size++;pthread_mutex_unlock(&(pool->queue_lock));/*等待队列中有任务了,唤醒一个等待线程,如果所有线程都在忙碌,这句没有任何作用*/pthread_cond_signal(&(pool->queue_ready));return 0;
}int pool_destroy()
{if(pool->destroy)return -1;pool->destroy = 1;/*唤醒所有等待线程,线程池要销毁了*/pthread_cond_broadcast(&(pool->queue_ready));/*阻塞等待线程退出,否则变成僵尸了*/int i = 0;for(i=0; i<pool->max_thread_num; i++){pthread_join(pool->threadid[i], NULL);}free(pool->threadid);thread_job *head = NULL;while(pool->queue_head != NULL){head = pool->queue_head;pool->queue_head = pool->queue_head->next;free(head);}/*条件变量和互斥量也要销毁*/pthread_mutex_destroy(&(pool->queue_lock));pthread_cond_destroy(&(pool->queue_ready));free(pool);pool = NULL;return 0;
}void* myprocess(void *arg)
{printf("threadid is 0x%x, working on task %d\n", (unsigned int)pthread_self(), *(int *)arg);sleep(1);return NULL;
} int main(int argc, char **argv)
{pool_init(3);/*初始话含有3个线程的线程池*/int *workingnum = (int *)malloc(sizeof(int)*10);int i = 0;for(i=0; i<10; i++){workingnum[i] = i;pool_add_job(myprocess, &workingnum[i]);}sleep(5);pool_destroy();free(workingnum);return 0;
}
Linux C下实现线程池相关推荐
- Linux下通用线程池的创建与使用
Linux下通用线程池的创建与使用 本文给出了一个通用的线程池框架,该框架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执行任务的轻重自动调整 ...
- 线程池是什么?什么情况下使用线程池?使用线程的好处是什么?
线程池:是一种多线程处理形式,处理线程时将任务添加到队列里,等创建好线程再执行队列里任务.线程池的线程都是后台线程.每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中. 什么情况下使 ...
- 一个Linux下C线程池的实现
什么时候需要创建线程池呢?简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽 视,这时也是线程池该出场的机会了.如果线程创建和销毁时间相比 ...
- 一个Linux下C线程池的实现(转)
1.线程池基本原理 在传统服务器结构中, 常是 有一个总的 监听线程监听有没有新的用户连接服务器, 每当有一个新的 用户进入, 服务器就开启一个新的线程用户处理这 个用户的数据包.这个线程只服务于这个 ...
- Linux下简单线程池的实现
线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收.所以 ...
- linux进程池 自动增长,linux下C 线程池的原理讲解和代码实现(能自行伸缩扩展线程数)...
什么线程池,为什么要使用线程池?下面是一个比喻. 阶段一.一个医院,每天面对成千上万的病人,处理方式是:来一个病人找来一个医生处理,处理完了医生也走了.当看病时间较短的时候,医生来去的时间,显得尤为费 ...
- Linux下C线程池的实现
如何在嵌入式开发板上内置网页,通过多个客服端来同时访问呢?因为需要大量线程来处理网页的任务,为了避免频繁的申请释放线程所带来的开销,使用了线程池来操作! 源代码: //服务端监听客服端访问网页的请求 ...
- 【Linux系统编程】线程池
00. 目录 文章目录 00. 目录 01. 线程池原理 02. 线程池应用实例 03. 线程池代码 04. 附录 01. 线程池原理 在传统服务器结构中,常是有一个总的监听线程监听有没有新的用户连接 ...
- Linux 多线程(附带线程池代码加注释)
目录 01. Linux线程概念 01.1 什么是线程 01.1.1 轻量级进程ID与进程ID之间的区别 01.1.2 总结(重点) 01.2 线程的优点 01.3 线程的缺点 01.4 线程异常 0 ...
最新文章
- html设置右边界,CSS边界(margin)——CSS实验室
- 关于机器学习算法的16个技巧
- CPU是怎样制造的?解析intel Core i7生产全过程
- python邮件添加附件_如何向电子邮件python添加多个附件
- SVG 图像入门教程
- 剑指offer 面试32题
- iphone输入法换行_【每日一技】iPhone输入法不能换行的痛点,用这招0.5秒解决
- Kienct与Arduino学习笔记(2) 深度图像与现实世界的深度图的坐标
- Win8下Qualcomm Atheros AR9285网卡改mac
- Java学生成绩管理系统主界面和登录界面参考
- 算法精解(一):C语言描述(链表)
- 猿辅导(实习800/天)面试算法题详解
- 五家共井 穷举法_测井曲线代码一览表
- 女人如何获取安全感?
- 澳洲计算机信息安全专业,澳洲网络信息安全专业有哪些牛校?本科硕士有哪些方向可以选择?...
- 民宿管理系统课程设计_民宿室内设计毕业设计
- Help library 安装arcobjects for .NET异常问题
- 搜狗输入法5.0正式版发布 首创云计算输入
- CG中的深度学习 |Siggraph 2017 相关论文总结
- C/C++、OS、网络面经
热门文章
- 子元素超出了父元素的高度_T恤定制融入中国元素,美出新高度
- 2015快捷键在哪里设置_炒股软件的选择通达信软件的基本设置
- sql查询 关联帖子_从零学会sql,复杂查询
- java 字符转化字符串_【转载】java字符串的各种编码转换
- android gridview固定行数据,如何在Android gridview中为行设置不同的列
- 转载 1-EasyNetQ介绍(黄亮翻译) https://www.cnblogs.com/HuangLiang/p/7105659.html
- java高并发下的数据安全
- 并查集:POJ1182-食物链(并查集比较高端的应用)
- Python基础day4 函数对象、生成器 、装饰器、迭代器、闭包函数
- 盘点游戏行业的那些干货网站