C 线程池 thread_pool

thread_pool.h

#ifndef THREAD_POOL_H  
#define THREAD_POOL_H  
  
#include <stdlib.h>  
#include <stdio.h>  
#include <pthread.h>  
typedef void *(*process)(void *arg);  
  
typedef struct _thread_worker_t  
{  
    process fun;  
    void *arg;  
    struct _thread_worker_t *next;  
  
}thread_worker_t;  
  
typedef struct _thread_pool_t  
{  
    pthread_mutex_t mutex;  
    pthread_cond_t cond; 
    int shutdown;//是否销毁线程池
    int thread_total;//初始化创建的线程个数
    int queue_size;//请求线程的数量  
    pthread_t *thread_id;//线程ID数组
    thread_worker_t *head;//用链表管理线程请求
}thread_pool_t;  
  
int thread_pool_init(thread_pool_t **pool,int num);  
  
int thread_pool_add_worker(thread_pool_t *pool,process fun,void *arg);  

int thread_pool_destroy (thread_pool_t *pool);

#endif // THREAD_POOL_H 


thread_pool.c

#include "thread_pool.h"  
  
  
static void* thread_routine(void *arg)  
{  
    //消费线程,从线程池中的head中获取头结点  
    thread_pool_t *pool = (thread_pool_t *)arg;  
    thread_worker_t *worker = NULL;  
    while(1)  
    {  
        pthread_mutex_lock(&(pool->mutex));  
        while(pool->queue_size == 0 && !pool->shutdown)  
        {  
            //池中还未有请求线程的 queue  
            //pthread_cond_wait是一个原子操作,等待前会解锁,唤醒后会加锁*/
            fprintf(stdout,"process[%lu] condtion wait...\n",pthread_self());  
            pthread_cond_wait(&(pool->cond),&(pool->mutex));  
            fprintf(stdout,"process[%lu] wake up...\n",pthread_self());  
        }
        /*线程池要销毁了*/  
        if (pool->shutdown)  
        {  
            /*遇到break,continue,return等跳转语句,千万不要忘记先解锁*/  
            pthread_mutex_unlock (&(pool->mutex));  
            printf ("thread 0x%lu will exit\n", pthread_self ());  
            pthread_exit (NULL);  
        } 
        
        fprintf(stdout,"queue_size = %d\n",pool->queue_size);  
        //消费请求的线程  
        pool->queue_size--;  
        //将头节点移除出线程池链表中  
        worker = pool->head;  
        pool->head = worker->next;  
  
        pthread_mutex_unlock(&(pool->mutex));  
        //执行队列中的任务  
        (*worker->fun)(worker->arg);  
        free(worker);  
        worker = NULL;  
    }  
    return NULL;  
}  
  
int thread_pool_init(thread_pool_t **pool,int num)  
{  
    if(num <= 0)  
    {  
        fprintf(stdout,"parameter error,[%s][%d]\n",__FILE__,__LINE__);  
        return -1;  
    }  
    thread_pool_t * tmp = NULL;  
    tmp = (thread_pool_t *)calloc(1,sizeof(thread_pool_t));  
    if(tmp == NULL)  
    {  
        fprintf(stdout,"calloc error,[%s][%d]\n",__FILE__,__LINE__);  
        return -1;  
    }  
    *pool = tmp;  
    pthread_mutex_init(&(tmp->mutex),NULL);  
    pthread_cond_init(&(tmp->cond),NULL);  
    tmp->queue_size = 0;//还未有请求线程队列  
    tmp->shutdown = 0;
    tmp->thread_id = (pthread_t *)calloc(1,num*sizeof(pthread_t));  
    if(tmp->thread_id == NULL)  
    {  
        fprintf(stdout,"calloc error,[%s][%d]\n",__FILE__,__LINE__);  
        free(tmp);  
        tmp = NULL;  
        return -1;  
    }  
      
    pthread_attr_t attr;  
    //创建线程  
    int idx = 0;  
    int ret;  
    for(; idx < num; idx++)  
    {  
        ret = pthread_attr_init(&attr);    
        if(0 != ret)    
        {    
            return -1;    
        }    
            
        ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);    
        if(0 != ret)    
        {    
            return -1;    
        }    
          
        pthread_create(&(tmp->thread_id[idx]),&attr,thread_routine,tmp);  
    }  
    return 0;  
  
}  
  
  
int thread_pool_add_worker(thread_pool_t *pool,process fun,void *arg)  
{  
    thread_worker_t *worker = NULL;  
    thread_worker_t *member = NULL;  
    worker = (thread_worker_t *)calloc(1,sizeof(thread_worker_t));  
    if(worker == NULL)  
    {  
        fprintf(stdout,"calloc error,[%s][%d]\n",__FILE__,__LINE__);  
        return -1;  
    }  
    worker->fun = fun;  
    worker->arg = arg;  
    worker->next = NULL;  
    //生产者,将节点插入到尾节点  
    pthread_mutex_lock(&(pool->mutex));  
    member = pool->head;  
    if(member != NULL)  
    {  
        //移到队尾  
        while(member->next != NULL)  
        {  
            member = member->next;  
        }  
        member->next = worker;  
    }  
    else  
    {  
        //头结点为空。说明队列中没有节点  
        pool->head = worker;  
    }  
    pool->queue_size++;  
      
    pthread_cond_signal(&(pool->cond));  
      
    pthread_mutex_unlock(&(pool->mutex));  
    return 0;  
}

int thread_pool_destroy (thread_pool_t *pool)  
{
    if (pool->shutdown)  
        return -1;/*防止两次调用*/ 
    pool->shutdown = 1;
    /*唤醒所有等待线程,线程池要销毁了*/  
    pthread_cond_broadcast (&(pool->cond));  
  
    //分离线程,系统的资源自动释放
    free (pool->thread_id);  
  
    /*销毁等待队列*/  
    thread_worker_t *worker = NULL;  
    while (pool->head != NULL)  
    {  
        worker = pool->head;  
        pool->head = worker->next;  
        free (worker);  
    }  
    /*条件变量和互斥量也别忘了销毁*/  
    pthread_mutex_destroy(&(pool->mutex));  
    pthread_cond_destroy(&(pool->cond));  
      
    free (pool);  
    /*销毁后指针置空是个好习惯*/  
    pool=NULL;  
    return 0;  
}



main.c

#include "thread_pool.h"  
  
#include <unistd.h>  
  
#define MAX 10  
  
void * myprocess(void *arg)  
{  
    int *pdata = (int *)(arg);  
    fprintf(stdout,"process[%lu] process data = %d...,\n",pthread_self(),*pdata);  
    if(*pdata % 2 == 0)  
    {  
        do  
        {  
            fprintf(stdout,"process[%lu] process running\n",pthread_self());  
            sleep(10);  
        }while(0);  
    }  
    return 0;  
}  
  
int main(void)  
{  
    thread_pool_t *pool;  
    thread_pool_init(&pool,10);
    int array[MAX + 20];  
    int idx = 0;  
    for(;idx < 30 ;idx++)  
    {  
        array[idx] = idx;  
        thread_pool_add_worker(pool,myprocess,(void*)&array[idx]);  
    }
    
  
    sleep(10);
    
    thread_pool_destroy(pool);
     
    pause();  
    return 0;  
}  



makefile:

.PHONY:clean all
CC=g++
CFLAGS=-Wall -g
BIN= main
all:$(BIN)
%.o:%.c
	$(CC) $(CFLAGS) -c $< -o $@

main: thread_pool.o main.o
	$(CC) $(CFLAGS) $^ -o $@ -lpthread
clean:
	rm -f *.o $(BIN)





测试结果:

实现创建10个线程,这10个线程等到有任务加入,出于条件等待中,当客户讲任务加入到队列中时,线程争抢资源执行自己的回调函数。有些进程一直运行(if i % 2 == 0),故不能再去队列中消费任务,这等价于该线程未完成任务,

卡在(*worker->fun)(worker->arg),反之继续执行消费任务,最后观察发现有10个线程任然在运行,调用thread_pool_destroy向所有等待中的线程发送醒来信号,然后告诉所有线程退出。

pool的shutdown变量控制着整个线程的状态,没有这个将不能杀死这10个线程,注意while(pool->queue_size == 0 && !pool->shutdown)



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值