一个简单线程池的实现

1.用于执行大量相对短暂的任务

2.当任务增加的时候能够动态的增加线程池中线程的数量直到达到一个阈值

3.当任务执行完毕的时候,能够动态的销毁线程池中线程

4.该线程池的实现本质上也是生产者与消费模式的应用,生产者线程向任务队列中添加任务,一旦队列有任务

    到来,如果有等待线程就唤醒来执行任务,如果没有等待线程并且线程数没有达到阈值,就创建新线程来执行任务


线程池线程的数量:

计算密集型任务:线程个数=CPU个数--》(执行任务的时候很少阻塞,不经常被外界打扰)

I/O密集型任务:当执行任务的时候经常会被I/O中断,线程会被挂起线程个数 > CPU个数

main.c

#include "threadpool.h"
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

void* mytask(void *arg)
{
	printf("thread 0x%0x is working on task%d\n",(int)pthread_self(),*(int*)arg);
	sleep(1);
	free(arg);
	return NULL;
}


int main()
{
	pthreadpool_t pool;
	pthreadpool_init(&pool,3);
	
	int i;
	for(i = 0;i < 10;i++)
	{
		int *arg =(int *)malloc(sizeof(int));
		*arg = i;
		ptheadpool_add_task(&pool,mytask,(void*)arg);
	}
	
	threadpool_destroy(&pool);
	return 0;
}



condition.h
#ifndef _CONDITION_H_
#define _CONDITION_H_

#include<pthread.h>

typedef struct condition
{
	pthread_mutex_t pmutex;
	pthread_cond_t pcond;

}condition_t;

int condition_init(condition_t *cond);
int condition_lock(condition_t *cond);
int condition_unlock(condition_t *cond);
int condition_wait(condition_t *cond);
int condition_timewait(condition_t *cond);
int condition_signal(condition_t *cond);
int condition_broadcast(condition_t *cond);
int condition_destroy(condition_t *cond);


#endif

condition.h

#include <condition.h>

/*
typedef struct condition
{
	pthread_mutex_t pmutex;
	pthread_cond_t pcond;

}condition_t;
*/

int condition_init(condition_t *cond)
{
	int status;
	if((status = pthread_mutex_init(&cond->pmutex,NULL))<0)
	{
		return status;
	}
	if((status = pthread_cond_init(&cond->pcond,NULL))<0)
	{
		return status;
	}
	return status;

}

int condition_lock(condition_t *cond)
{
	return pthread_mutex_lock(&cond->pmutex);
}

int condition_unlock(condition_t *cond)
{
	return pthread_mutex_unlock(&cond->pmutex);
}

int condition_wait(condition_t *cond)
{
	return pthread_cond_wait(&cond->pcond,&cond->pmutex);
}

int condition_timewait(condition_t *cond,const struct timespec *abstime)
{
	return pthread_cond_timedwait(&cond->pcond,&cond->pmutex,abstime);	
}

int condition_signal(condition_t *cond)
{
	return pthread_cond_signal(&cond->pcond);
}

int condition_broadcast(condition_t *cond)
{
	return pthread_cond_broadcast(&cond->pcond);
}

int condition_destroy(condition_t *cond)
{
	int status;
	if((status = pthread_mutex_destroy(&cond->pmutex,NULL)) < 0)
	{
		return status;
	}
	if((status = pthread_cond_destroy(&cond->pcond)) < 0)
	{
		return status;
	}
		return status;
}







pthreadpool.h

//任务结构体,将任务放入队列由线程池中的线程来执行

typedef struct task
{
	void*(*run)(void* arg);
	void* arg;
	struct task * next;
}task_t;

//线程池结构体
typedef struct threadpool
{
	condition_t ready;	//任务准备就绪或者线程销毁通知
	task_t *first;		//任务队列头指针
	task_t *last		//任务队列尾指针
	int counter;		//线程池中当前线程数量
	int max_threads;	//线程池中最大允许的线程数
	int quit;		//销毁线程池中时候置1
}threadpool_t;

//初始化线程池
void threadpool_init(threadpool_t *pool,int threads);
//往线程池中添加任务
threadpool_add_task(threadpool_t * pool,void *(*run)(void *arg),void *arg);
//销毁线程池
void threadpool_destroy(threadpool_t *pool);



pthreadpool.c

#include "pthreadpool.h"
#include <string.h>
#include <errno.h>
#include <time.h>
/*
	condition_t ready;	//任务准备就绪或者线程销毁通知
	task_t *first;		//任务队列头指针
	task_t *last		//任务队列尾指针
	int counter;		//线程池中当前线程数量
	int max_threads;	//线程池中最大允许的线程数
	int quit;		//销毁线程池中时候置1
*/


void* thread_routine(void *arg)
{
	struct timespec abstime;
	int timeout;
	printf("thread 0x%x is starting\n",(int)pthread_self());
	threadpool_t * pool = (threadpool_t *)arg;
	while(1)
	{
		timeout = 0;
		condition_lock(&pool->ready);
		pool->idle++;
		//等待队列有任务到来或者线程池销毁通知
		while(pool->first ==NULL && !pool->quit)
		{
			printf("thread 0x%s is waiting\n",(int)pthread_self());
			//condition_wait(&pool->ready);
			clock_gettime(CLOCK_REALTIME,&abstime);
			abstime.tv_sec += 2;
			int status = condition_timewait(&pool->ready,&abstime);
			if(status == ETIMEDDUT)
			{
				printf("thread is wait time out");
				timeout = 1;
				break;
			}
				
		}
		//等待到条件,处于工作状态
		pool->idle--;
		//等待到任务
		if(pool->first != NULL)
		{
			//从头取出任务
			tast_t *t = pool->first;
			pool->first = t->next;
			//执行任务需要一定的时间,所以要先解锁,以便生产者线程能够往
			//队列中添加任务,其他消费者能够进入等待任务
			condition_unlock(&pool->ready);
			t->run(t->arg);
			free(t);
			condition_unlock(&pool->ready);
		}
		//如果等待到线程销毁通知
		if(pool->quit && pool->first == NULL)
		{
			pool->counter--;
			if(pool->counter == 0)
			{
				condition_signal(&pool->ready);
			}
			condition_unlock(&pool->ready);
			//跳出循环之前要解锁
			break;
		}
		if(pool->timeout && pool->first == NULL)
		{
			pool->counter--;
			condition_unlock(&pool->ready);
			break;
		}
		condition_unlock(&pool->ready);

	}
	return NULL;
}

//初始化线程池
void threadpool_init(threadpool_t *pool,int threads)
{
	//对线程池中的各个字段初始化
	condition_init(pool->ready);
	pool->first = NULL;
	pool->last = NULL;
	pool->counter = 0;
	pool->idle = 0;
	pool->max_threads = threads;
	pool->quit = 0;
	
}
//往线程池中添加任务
threadpool_add_task(threadpool_t * pool,void *(*run)(void *arg),void *arg)
{
	//创建新的任务
	task_t *newtask = (task_t)malloc(sizeof(task_t));
	newtask->run = run;
	newtask->arg = arg;
	newtask->next = NULL;
	
	//将任务加到队列中
	condition_lock(&pool->ready);
	if(pool->first ==NULL)
	{
		pool->first = newtask;
		pool->last = newtask;
	}
	else
	{
		pool->last->next = newtask;
		pool->last = newtask;	
	}
	
	//如果有等待的线程,就唤醒其中一个
	if(pool-idle > 0)
	{
		condition_signal(&pool->ready);
	]
	else if(pool->counter < pool->pool->max_threads)
	{
		//没有等待线程,并且当前线程数不超过最大线程数,就创建一个新线程
		pthread_t tid;
		pthread_create(&tid,NULL,thread_routine,pool);
		pool->couter++;	
	}	
	condition_unlock(&pool->ready);
	
	
}
//销毁线程池
void threadpool_destroy(threadpool_t *pool)
{
	if(pool->quit)
	{
		return;
	}
	condition_lock(&pool->ready);
	pool->quit = 1;
	if(pool->counter > 0)
	{
		if(pool->idle > 0)
		{
			condition_broadcast(&pool->ready);

			//处于执行任务状态的线程,不会收的广播
			//线程池需要等待执行任务状态中的线程全部退出
			while(pool->counter > 0)
			{
				condition_wait(&pool->ready);
			}
		}
	}
	condition_unlock(&pool->ready);
	condition_destroy(&pool->ready);


}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值