下面是原文链接,我是照着敲的。。。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下实现线程池相关推荐

  1. Linux下通用线程池的创建与使用

    Linux下通用线程池的创建与使用 本文给出了一个通用的线程池框架,该框架将与线程执行相关的任务进行了高层次的抽象,使之与具体的执行任务无关.另外该线程池具有动态伸缩性,它能根据执行任务的轻重自动调整 ...

  2. 线程池是什么?什么情况下使用线程池?使用线程的好处是什么?

    线程池:是一种多线程处理形式,处理线程时将任务添加到队列里,等创建好线程再执行队列里任务.线程池的线程都是后台线程.每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中. 什么情况下使 ...

  3. 一个Linux下C线程池的实现

    什么时候需要创建线程池呢?简单的说,如果一个应用需要频繁的创建和销毁线程,而任务执行的时间又非常短,这样线程创建和销毁的带来的开销就不容忽 视,这时也是线程池该出场的机会了.如果线程创建和销毁时间相比 ...

  4. 一个Linux下C线程池的实现(转)

    1.线程池基本原理 在传统服务器结构中, 常是 有一个总的 监听线程监听有没有新的用户连接服务器, 每当有一个新的 用户进入, 服务器就开启一个新的线程用户处理这 个用户的数据包.这个线程只服务于这个 ...

  5. Linux下简单线程池的实现

    线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收.所以 ...

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

    什么线程池,为什么要使用线程池?下面是一个比喻. 阶段一.一个医院,每天面对成千上万的病人,处理方式是:来一个病人找来一个医生处理,处理完了医生也走了.当看病时间较短的时候,医生来去的时间,显得尤为费 ...

  7. Linux下C线程池的实现

    如何在嵌入式开发板上内置网页,通过多个客服端来同时访问呢?因为需要大量线程来处理网页的任务,为了避免频繁的申请释放线程所带来的开销,使用了线程池来操作! 源代码: //服务端监听客服端访问网页的请求 ...

  8. 【Linux系统编程】线程池

    00. 目录 文章目录 00. 目录 01. 线程池原理 02. 线程池应用实例 03. 线程池代码 04. 附录 01. 线程池原理 在传统服务器结构中,常是有一个总的监听线程监听有没有新的用户连接 ...

  9. Linux 多线程(附带线程池代码加注释)

    目录 01. Linux线程概念 01.1 什么是线程 01.1.1 轻量级进程ID与进程ID之间的区别 01.1.2 总结(重点) 01.2 线程的优点 01.3 线程的缺点 01.4 线程异常 0 ...

最新文章

  1. html设置右边界,CSS边界(margin)——CSS实验室
  2. 关于机器学习算法的16个技巧
  3. CPU是怎样制造的?解析intel Core i7生产全过程
  4. python邮件添加附件_如何向电子邮件python添加多个附件
  5. SVG 图像入门教程
  6. 剑指offer 面试32题
  7. iphone输入法换行_【每日一技】iPhone输入法不能换行的痛点,用这招0.5秒解决
  8. Kienct与Arduino学习笔记(2) 深度图像与现实世界的深度图的坐标
  9. Win8下Qualcomm Atheros AR9285网卡改mac
  10. Java学生成绩管理系统主界面和登录界面参考
  11. 算法精解(一):C语言描述(链表)
  12. 猿辅导(实习800/天)面试算法题详解
  13. 五家共井 穷举法_测井曲线代码一览表
  14. 女人如何获取安全感?
  15. 澳洲计算机信息安全专业,澳洲网络信息安全专业有哪些牛校?本科硕士有哪些方向可以选择?...
  16. 民宿管理系统课程设计_民宿室内设计毕业设计
  17. Help library 安装arcobjects for .NET异常问题
  18. 搜狗输入法5.0正式版发布 首创云计算输入
  19. CG中的深度学习 |Siggraph 2017 相关论文总结
  20. C/C++、OS、网络面经

热门文章

  1. 子元素超出了父元素的高度_T恤定制融入中国元素,美出新高度
  2. 2015快捷键在哪里设置_炒股软件的选择通达信软件的基本设置
  3. sql查询 关联帖子_从零学会sql,复杂查询
  4. java 字符转化字符串_【转载】java字符串的各种编码转换
  5. android gridview固定行数据,如何在Android gridview中为行设置不同的列
  6. 转载 1-EasyNetQ介绍(黄亮翻译) https://www.cnblogs.com/HuangLiang/p/7105659.html
  7. java高并发下的数据安全
  8. 并查集:POJ1182-食物链(并查集比较高端的应用)
  9. Python基础day4 函数对象、生成器 、装饰器、迭代器、闭包函数
  10. 盘点游戏行业的那些干货网站