linux线程池

线程池

1、任务和线程池结构体

#ifndef __THREADPOOL_H__
#define __THREADPOOL_H__

#include "condition.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 idle;			// 空闲线程数
	int max_threads;	// 线程池允许的最大线程数
	int quit;			// 线程的退出标记,1表示退出
}threadpool_t;

// 初始化线程池
// @pool - 线程池对象
// @threads - 线程池的最大数量
void threadpool_init(threadpool_t *pool, int threads);

// 向线程池中添加任务
// @run - 任务回调函数
void threadpool_add_task(threadpool_t *pool, void *(*run)(void*), void *arg);

// 销毁线程池
void threadpool_destroy(threadpool_t *pool);

#endif //__THREADPOOL_H__

2、执行任务的条件

#ifndef __CONDITION_H__
#define __CONDITION_H__

#include <pthread.h>

typedef struct condtion{
	pthread_mutex_t mutex;
	pthread_cond_t cond;
}condition_t;

void condition_init(condition_t *cond);
void condition_lock(condition_t *cond);
void condition_unlock(condition_t *cond);
void condition_wait(condition_t *cond);
int condition_timedwait(condition_t *cond, const struct timespec *abstime);
void condition_signal(condition_t *cond);
void condition_broadcast(condition_t *cond);
void condition_destroy(condition_t *cond);

#endif //__CONDITION_H__
#include "condition.h"

void condition_init(condition_t *cond)
{
	pthread_mutex_init(&cond->mutex, NULL);
	pthread_cond_init(&cond->cond, NULL);
}

void condition_lock(condition_t *cond)
{
	pthread_mutex_lock(&cond->mutex);
}

void condition_unlock(condition_t *cond)
{
	pthread_mutex_unlock(&cond->mutex);
}

void condition_wait(condition_t *cond)
{
	pthread_cond_wait(&cond->cond, &cond->mutex);
}

int condition_timedwait(condition_t *cond, const struct timespec *abstime)
{
	return pthread_cond_timedwait(&cond->cond, &cond->mutex, abstime);
}

void condition_signal(condition_t *cond)
{
	pthread_cond_signal(&cond->cond);
}

void condition_broadcast(condition_t *cond)
{
	pthread_cond_broadcast(&cond->cond);
}

void condition_destroy(condition_t *cond)
{
	pthread_mutex_destroy(&cond->mutex);
	pthread_cond_destroy(&cond->cond);
}

3、线程池实现

#include "threadpool.h"

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

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;
}

void *route(void *arg)
{
	threadpool_t *pool = (threadpool_t*)arg;
	int timeout = 0;
	
	while ( 1 ) {
		condition_lock(&pool->ready);
		timeout = 0;	
		pool->idle++;
		
		// 等待任务队列有任务到来或线程销毁通知
		while ( pool->first == NULL && pool->quit == 0 ) {
			//condition_wait(&pool->ready);
			struct timespec ts;
			clock_gettime(CLOCK_REALTIME, &ts);
			ts.tv_sec += 2;
			int ret = condition_timedwait(&pool->ready, &ts);
			if ( ret == ETIMEDOUT ) {
				printf("%#X thread timeout!\n", (int)pthread_self());
				timeout = 1;
				break;
			}
		}
		// 等待到条件,空闲线程数量减少
		pool->idle--;
	
		if ( pool->first != NULL ) {
			// 从队头取任务进行执行
			task_t *t = pool->first;
			pool->first = t->next;
			// 防止run函数执行的时间太长
			condition_unlock(&pool->ready);
			t->run(t->arg);
			condition_lock(&pool->ready);
			free(t);
		}
	
		// 等待到线程池销毁通知,并且任务都执行完毕
		if ( pool->quit == 1 && pool->first == NULL ) {
			pool->counter--;
			if ( pool->counter == 0 )
				condition_signal(&pool->ready);
			// 跳出循环之前,要记得解锁
			condition_unlock(&pool->ready);
			break;
		}
	
		// 超时处理
		if ( timeout == 1 && pool->first == NULL ) {
			pool->counter--;
			condition_unlock(&pool->ready);
			break;
		}
		
		condition_unlock(&pool->ready);
	}
}

void threadpool_add_task(threadpool_t *pool, void *(*run)(void*), void *arg)
{
	task_t *newtask = malloc(sizeof(task_t));
	newtask->run = run;
	newtask->arg = arg;
	newtask->next = NULL;
	
	condition_lock(&pool->ready);
	if ( pool->first == NULL )
		pool->first = newtask;
	else
		pool->last->next = newtask;
	pool->last = newtask;
	
	if ( pool->idle > 0 ) {
		condition_signal(&pool->ready);
	} else if ( pool->counter < pool->max_threads ) {
		pthread_t tid;
		pthread_create(&tid, NULL, route, pool);
		pool->counter++;
	}

	condition_unlock(&pool->ready);
}

void threadpool_destroy(threadpool_t *pool)
{
	if ( pool->quit == 1 )
		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);
}

4、测试代码

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

void *mytask(void *arg)
{
	printf("thread %#X working on %d\n", pthread_self(), (int)arg);
	sleep(1);
}

int main( void )
{
	threadpool_t pool;
	
	threadpool_init(&pool, 3);
	
	int i;
	for (i=0; i<10; i++) {
		dd_tathreadpool_ask(&pool, mytask, (void*)i);
	}
	
	//sleep(15);
	threadpool_destroy(&pool);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值