线程池的实现

    之前在很多博客中看到一个关于线程池的实现代码,完全一致,于是产生了一点兴趣,于是将代码进行了编译,吓死,全是错误,于是,进行了修改,并运行通过。

(1)用户程序向任务队列中添加任务。
(2)创建线程池,线程睡眠,处于空闲状态。
(3)唤醒线程,线程池中的线程执行函数取出任务队列中的任务。
(4)执行任务中的调用函数,完成工作。
(5)线程池任务执行完判断,如果没有程序调用,线程继续睡眠。
(6)调用销毁函数对线程池进行销毁。
头文件pool.h如下。其中CThread_Worker为封装的任务,存放在链表上,等待线程执行该任务中的函数process,而CThread_pool是封装的线程池结构,线程池在创建的时候,会初始化该结构。pool_init()函数为线程池初始化。thread_routine()函数为线程的执行函数。myprocess()函数为任务执行的内容。函数pool_add_worker()的功能为将任务添加到等待队列上。poll_destroy()的功能为摧毁线程池,释放一切资源。

  1 #ifndef _POOL_H
  2 #define _POOL_H
  3 
  4 #include <stdio.h>
  5 #include <unistd.h>
  6 #include <stdlib.h>
  7 #include <sys/types.h>
  8 #include <pthread.h>
  9 #include <assert.h>
 10 /*
 11  *线程池所有运行和等待的任务都是一个CThread_Worker
 12  *由于所有任务都在链表里,所以是一个链表结构
 13  */
 14 typedef struct worker{
 15     /*回调函数,在任务运行时调用此函数*/
 16     void *(*process)(void *arg);
 17     void *arg;/*回调函数的参数*/ 
 18     struct worker *next; 
 19 }CThread_Worker; 
 20  
 21 /*线程池结构*/ 
 22 typedef struct{
 23     pthread_mutex_t queue_lock;
 24     pthread_cond_t queue_ready;
 25 
 26     /*链表结构*/
 27     CThread_Worker *queue_head;
 28 
 29     /*是否摧毁线程池*/
 30     int shutdown;
 31     pthread_t *threadid;
 32 
 33     /*线程池中允许活动线程的数量*/
 34     int max_thread_num;
 35 
 36     /*当前等待队列的任务数量*/
 37     int cur_queue_size;
 38 }CThread_Pool;
 39 
 40 extern void pool_init(int max_thread_num);
 41 extern void *thread_routine(void *arg);
 42 extern void *myprocess(void *arg);
 43 extern int pool_add_worker(void *(*process)(void *arg), void *arg);
 44 extern int pool_destroy();
 45 #endif
       线程的核心代码threadpool.c内容如下,实现线程池操作函数的功能。
  1 #include "pool.h"
  2 
  3 static CThread_Pool *pool = NULL;
  4 void *thread_routine(void *arg){
  5     printf("thread start 0x%x\n", pthread_self());
  6 
  7     while(1){
  8         pthread_mutex_lock(&(pool->queue_lock));
  9 
 10         /*如果等待队列为0并且不摧毁线程池,则线程处于阻塞状态*/
 11         while(pool->cur_queue_size == 0 && !pool->shutdown){
 12             printf("thread 0x%x is waiting\n", pthread_self());
 13           pthread_cond_wait(&(pool->queue_ready), &(pool->queue_lock));
 14         }
 15 
 16         /*线程池如果摧毁*/
 17         if(pool->shutdown){
 18             pthread_mutex_unlock(&(pool->queue_lock));
 19             printf("thread 0x%x will exit\n", pthread_self());
 20             pthread_exit(NULL);
 21         }
 22 
 23         printf("thread 0x%x is starting to work\n", pthread_self());
 24 
 25         assert(pool->cur_queue_size != 0);
 26         assert(pool->queue_head != NULL);
 27 
 28         /*等待队列长度减1,并取出链表中的头元素*/
 29         pool->cur_queue_size--;
 30         CThread_Worker *worker = pool->queue_head;
 31         pool->queue_head = worker->next;
 32 
 33         pthread_mutex_unlock(&(pool->queue_lock));                                                                                                                                   
 34 
 35         /*调用回调函数,执行任务*/
 36         (*(worker->process))(worker->arg);
 37 
 38         free(worker);
39         worker = NULL;
 40     }
 41     pthread_exit(NULL);
 42 }
 43 void pool_init(int max_thread_num){
 44     pool = (CThread_Pool *)malloc(sizeof(CThread_Pool));
 45 
 46     pthread_mutex_init(&(pool->queue_lock), NULL);
 47     pthread_cond_init(&(pool->queue_ready), NULL);
 48 
 49     pool->queue_head = NULL;
 50 
 51     pool->max_thread_num = max_thread_num;
 52     pool->cur_queue_size = 0;
 53 
 54     pool->shutdown = 0;
 55 
 56     pool->threadid = 
            (pthread_t *)malloc(max_thread_num * sizeof(pthread_t));
 57 
 58     int i = 0;
 59     for(i = 0; i < max_thread_num; i++){
 60         pthread_create(&(pool->threadid[i]), 
                              NULL, thread_routine, NULL);
 61     }
 62 }
 63 /*测试代码,添加到线程池的任务*/
 64 void *myprocess(void *arg){
 65     printf("threadid is 0x%x, working on task %d\n",
                          pthread_self(), *(int *)arg);
 66     sleep(1);
 67     return NULL;                                                                                                                                                                     
 68 }
 69 /*向线程池中添加任务*/
 70 int pool_add_worker(void *(*process)(void *arg), void *arg){
 71  /*构造一个新任务*/
 72 CThread_Worker *newworker = 
                    (CThread_Worker *)malloc(sizeof(CThread_Worker));
 73     newworker->process = process;
 74     newworker->arg = arg;
 75     newworker->next = NULL;
 76 
 77     pthread_mutex_lock(&(pool->queue_lock));
 78                                                                                                                                                                                      
 79     /*把任务放到等待队列中*/
 80     CThread_Worker *member = pool->queue_head;
 81     if(member != NULL){
 82         while(member->next != NULL){
 83             member = member->next;
 84         }
 85         member->next = newworker;
 86     }
 87     else{
 88         pool->queue_head = newworker;
 89     }
 90 
 91     assert(pool->queue_head != NULL);
 92 
 93     pool->cur_queue_size++;
 94 
 95     pthread_mutex_unlock(&(pool->queue_lock));
 96 
 97     /*等待队列中有任务,唤醒一个等待线程*/
 98     pthread_cond_signal(&(pool->queue_ready));
 99 
100 }
101 
102 /*
103  *摧毁线程池,等待队列中的任务不会再被执行,
104  *但是正在运行的线程会一直把任务运行完后再退出
105  */
106 int pool_destroy(){
107     if(pool->shutdown){
108         return -1;
109     }
110     pool->shutdown = 1;
111                                                                                                                                                                                      
112     /*唤醒所有等待的线程,线程池要摧毁了*/
113     pthread_cond_broadcast(&(pool->queue_ready));
114 
115     /*阻塞等待线程退出,否则就成为僵尸进程了*/
116     int i;
117     for(i = 0; i<pool->max_thread_num; i++){
118         pthread_join(pool->threadid[i], NULL);
119     }
120     free(pool->threadid);
121 
122     /*销毁等待队列*/
123     CThread_Worker *head = NULL;
124     while(pool->queue_head != NULL){
125         head = pool->queue_head;
126         pool->queue_head = pool->queue_head->next;
127         free(head);
128     }
129 
130     pthread_mutex_destroy(&(pool->queue_lock));
131     pthread_cond_destroy(&(pool->queue_ready));
132 
133     free(pool);
134     pool = NULL;
135 
136     return 0;
137 }
测试代码main.c内容如下。
  1 #include "pool.h"
  2 
  3 int main(int argc, const char *argv[])
  4 {
  5     /*线程池中最多三个活动线程*/
  6     pool_init(3);
  7 
  8     sleep(1);
  9     /*连续向池中投入10个任务*/
 10     int *workingnum = (int *)malloc(sizeof(int) * 10);
 11 
 12     int i;
 13     for(i = 0; i < 10; i++){                                                                                                                                                         
 14         workingnum[i] = i;
 15         pool_add_worker(myprocess, &workingnum[i]);
 16     }
 17 
 18     sleep(5);
 19 
 20     /*摧毁线程池*/
 21     pool_destroy();
 22     free(workingnum);
 23     return 0;
 24 }
 工程管理器Makefile,示例如下。
  1 .PHONY: all clean
  2      
  3 all: test
  4      
  5 test: main.o threadpool.o
  6     gcc $^ -o $@ -lpthread                                                                                                                                                           
  7      
  8 %.o:%.c
  9     gcc -c $^ -o $@
 10      
 11 clean:
 12     rm -rf *.o test

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值