根据相关资料,自己实现的线程池

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #include <unistd.h>
  4 #include <pthread.h>
  5 #include <sys/types.h>
  6
  7 typedef struct CThread_worker
  8 {
  9     void *(*process)(void *arg);
 10     void *arg;
 11     struct CThread_worker *next;
 12 }CThread_worker;
 13
 14
 15 typedef struct
 16 {
 17     pthread_mutex_t queue_head;
 18     pthread_cond_t queue_ready;
 19
 20     struct CThread_worker *queue_worker;
 21     pthread_t *pthread_id;
 22
 23     int max_task_num;
 24     int cur_task_num;
 25     int shutdown;
 26
 27 }CThread_pool;
 28
 29 static CThread_pool *pool = NULL;
 30
 31 void pool_init(int);
 32 void add_task_to_pool(void *(*)(void *), void *);
 33 void *pthread_fun(void *);
 34 void pool_destroy();
 35 void *my_process(void *);
 36
 37 int main(int argc, char *argv[])
 38 {
 39     int max_task_num = 0;
 40     int i = 0;
 41     max_task_num = 5;
 42
 43     pool_init(max_task_num);
 44
 45     int *worker_num;
 46     worker_num = (int *)malloc(10 * sizeof(int));
 47     for (i=0; i<10; i++)
 48     {
 49         worker_num[i] = i;
 50         add_task_to_pool(my_process, &worker_num[i]);
 51     }
 52
 53     sleep(12);
 54     pool_destroy();
 55
 56     free(worker_num);
 57     worker_num = NULL;
 58
 59     return 0;
 60 }
 61
 62
 63 void pool_init(int num)
 64 {
 65     int i = 0;
 66     pool = (CThread_pool *)malloc(sizeof(CThread_pool));
 67
 68     pthread_mutex_init(&(pool->queue_head), NULL);
 69     pthread_cond_init(&(pool->queue_ready), NULL);
 70
 71     pool->queue_worker = NULL;
 72     pool->max_task_num = num;
 73     pool->cur_task_num = 0;
 74     pool->shutdown = 0;
 75     pool->pthread_id = (pthread_t *)malloc(num * sizeof(pthread_t));
 76
 77     for (i=0; i<num; ++i)
 78     {
 79         pthread_create(&(pool->pthread_id[i]), NULL, pthread_fun, NULL);
 80     }
 81
 82 }
 83
 84 void *pthread_fun(void *arg)
 85 {
 86     CThread_worker *worker = NULL;
 87
 88     printf("pthread %u is starting\n", (unsigned int)pthread_self());
 89     while (1)
 90     {
 91         pthread_mutex_lock(&(pool->queue_head));
 92         while (pool->cur_task_num == 0 && !pool->shutdown)
 93         {
 94             printf("pthread %u is waiting task...\n\n", (unsigned int)(pthread_self()));
 95             pthread_cond_wait(&(pool->queue_ready), &(pool->queue_head));
 96         }
 97         if (pool->shutdown)
 98         {
 99             /*线程退出之前,必须解锁,以让其他的线程得以访问该共享资源.*/
100             pthread_mutex_unlock(&(pool->queue_head));
101             printf("pthread %u is exiting\n", (unsigned int)pthread_self());
102             pthread_exit(NULL);
103         }
104
105         pool->cur_task_num--;
106
107         worker = pool->queue_worker;
108         pool->queue_worker = worker->next;
109 /*
110         while (worker->next != NULL)
111         {
112             worker = worker->next;
113         }
114 */
115         pthread_mutex_unlock(&(pool->queue_head));
116
117         (*(worker->process))(worker->arg);
118     }
119     pthread_exit(NULL);
120 }
121
122 void add_task_to_pool(void *(*my_process)(void *), void *arg)
123 {
124     CThread_worker *worker = NULL;
125     CThread_worker *p = NULL;
126
127     worker = (CThread_worker *)malloc(sizeof(CThread_worker));
128     worker->process = my_process;
129     worker->arg = arg;
130     worker->next = NULL;
131
132     pthread_mutex_lock(&(pool->queue_head));
133
134     p = pool->queue_worker;
135     if ( p == NULL)
136     {
137         pool->queue_worker = worker;
138     }
139     else
140     {
141         while (p->next != NULL)
142         {
143             p = p->next;
144         }
145         p->next = worker;
146     }
147
148     pool->cur_task_num++;
149
150     pthread_mutex_unlock(&(pool->queue_head));
151
152     pthread_cond_signal(&(pool->queue_ready));
153
154 }
155
156
157 void pool_destroy()
158 {
159     int i = 0;
160     CThread_worker *p = NULL;
161
162     pool->shutdown = 1;
163     /*唤醒等待该条件的所有线程.否则线程将处于阻塞状态,等待条件满足.*/
164     pthread_cond_broadcast(&(pool->queue_ready));
165     /*阻塞等待线程退出,否则成为僵尸线程.*/
166     for (i=0; i<pool->max_task_num; ++i)
167     {
168         pthread_join(pool->pthread_id[i], NULL);
169     }
170     free (pool->pthread_id);
171
172     while (pool->queue_worker != NULL)
173     {
174         p = pool->queue_worker;
175         pool->queue_worker = p->next;
176         free(p);
177     }
178     /*信号量和条件变量需要销毁.*/
179     pthread_mutex_destroy(&(pool->queue_head));
180     pthread_cond_destroy(&(pool->queue_ready));
181
182     free(pool);
183     /*为避免pool成为野指针,将其赋值为空.*/
184     pool = NULL;
185 }
186
187 void *my_process(void *task_id)
188 {
189     printf("thread %u is doing task %d\n",(unsigned int)pthread_self(), *(int *)task_id);
190     sleep(1);
191 }
时间: 2024-10-06 11:18:23

根据相关资料,自己实现的线程池的相关文章

java线程池相关知识点总结

Android中常见到的很多通用组件一般都离不开"池"的概念,如各种图片加载库,网络请求库,即使Android的消息传递机制中的Meaasge当使用Meaasge.obtain()就是使用的Meaasge池中的对象,因此这个概念很重要.本文将介绍的线程池技术同样符合这一思想. 线程池的优点:重用线程池中的线程,减少因对象创建,销毁所带来的性能开销;能有效的控制线程的最大并发数,提高系统资源利用率,同时避免过多的资源竞争,避免堵塞;能够多线程进行简单的管理,使线程的使用简单.高效. 线程

关于Java中线程池的解读

之前的面试中多次被问到线程池的相关内容,所以在之后的时间内我仔细的学习了一下线程池的相关内容. 1.使用线程池的意义 复用:类似WEB服务器等系统,长期来看内部需要使用大量的线程处理请求,而单次请求响应时间通常比较短,此时Java基于操作系统的本地调用方式大量的创建和销毁线程本身会成为系统的一个性能瓶颈和资源浪费.若使用线程池技术可以实现工作线程的复用,即一个工作线程创建和销毁的生命周期期间内可以执行处理多个任务,从而总体上降低线程创建和销毁的频率和时间,提升了系统性能. 流控:服务器资源有限,

Java线程池使用和分析(二) - execute()原理

相关文章目录: Java线程池使用和分析(一) Java线程池使用和分析(二) - execute()原理 execute()是 java.util.concurrent.Executor接口中唯一的方法,JDK注释中的描述是“在未来的某一时刻执行命令command”,即向线程池中提交任务,在未来某个时刻执行,提交的任务必须实现Runnable接口,该提交方式不能获取返回值.下面是对execute()方法内部原理的分析,分析前先简单介绍线程池有哪些状态,在一系列执行过程中涉及线程池状态相关的判断

C#多线程之线程池篇2

在上一篇C#多线程之线程池篇1中,我们主要学习了如何在线程池中调用委托以及如何在线程池中执行异步操作,在这篇中,我们将学习线程池和并行度.实现取消选项的相关知识. 三.线程池和并行度 在这一小节中,我们将学习对于大量的异步操作,使用线程池和分别使用单独的线程在性能上有什么差异性.具体操作步骤如下: 1.使用Visual Studio 2015创建一个新的控制台应用程序. 2.双击打开"Program.cs"文件,编写代码如下所示: 1 using System; 2 using Sys

Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理

相关文章目录: Java线程池ThreadPoolExecutor使用和分析(一) Java线程池ThreadPoolExecutor使用和分析(二) - execute()原理 Java线程池ThreadPoolExecutor使用和分析(三) - 终止线程池原理 以下是本文的目录大纲: 一.shutdown()  --  温柔的终止线程池 interruptIdleWorkers()  --  中断空闲worker tryTerminate()  --  尝试终止线程池 二.shutdown

从使用到原理学习Java线程池

来源:SilenceDut http://www.codeceo.com/article/java-threadpool-learn.html 线程池的技术背景 在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收. 所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁.如何利用已有对象来服务就是一个需要解决的关键问题,其实这

线程池的基本概念

线程池,是一种线程的使用模式,它为了降低线程使用中频繁的创建和销毁所带来的资源消耗与代价. 通过创建一定数量的线程,让他们时刻准备就绪等待新任务的到达,而任务执行结束之后再重新回来继续待命. 这就是线程池最核心的设计思路,「复用线程,平摊线程的创建与销毁的开销代价」. 相比于来一个任务创建一个线程的方式,使用线程池的优势体现在如下几点: 避免了线程的重复创建与开销带来的资源消耗代价 提升了任务响应速度,任务来了直接选一个线程执行而无需等待线程的创建 线程的统一分配和管理,也方便统一的监控和调优

MySQL线程池(THREAD POOL)的原理

MySQL常用(目前线上使用)的线程调度方式是one-thread-per-connection(每连接一个线程),server为每一个连接创建一个线程来服务,连接断开后,这个线程进入thread_cache或者直接退出(取决于thread_cache设置及系统当前已经cache的线程数目),one-thread-per-connection调度的好处是实现简单,而且能够在系统没有遇到瓶颈之前保证较小的响应时间,比较适合活跃的长连接的应用场景,而在大量短连接或者高并发情况下,one-thread

浅谈线程池(下):相关试验及注意事项

三个月,整整三个月了,我忽然发现我还有三个月前的一个小系列的文章没有结束,我还欠一个试验!线程池是.NET中的重要组件,几乎所有的异步功能依赖于线程池.之前我们讨论了线程池的作用.独立线程池的存在意义,以及对CLR线程池和IO线程池进行了一定说明.不过这些说明可能有些"抽象",于是我们还是要通过试验来"验证"这些说明.此外,我认为针对某个"猜想"来设计一些试验进行验证是非常重要的能力,如果您这方面的能力略有不足的话,还是尽量加以锻炼并提高吧. C

记5.28大促压测的性能优化&mdash;线程池相关问题

目录: 1.环境介绍 2.症状 3.诊断 4.结论 5.解决 6.对比java实现 废话就不多说了,本文分享下博主在5.28大促压测期间解决的一个性能问题,觉得这个还是比较有意思的,值得总结拿出来分享下. 博主所服务的部门是作为公共业务平台,公共业务平台支持上层所有业务系统(2C.UGC.直播等).平台中核心之一的就是订单域相关服务,下单服务.查单服务.支付回调服务,当然结算页暂时还是我们负责,结算页负责承上启下进行下单.结算.跳支付中心.每次业务方进行大促期间平台都要进行一次常规压测,做到心里