thread pool

/*
 * threadpool.h
 *
 *  Created on: 2016年5月11日
 *      Author: qiangqaz
 */

#ifndef THREADPOOL_H_
#define THREADPOOL_H_

#include <pthread.h>

typedef void (*CB_FUN)(void *);

//task structure
typedef struct task
{
	void *argv;				//task handler's arg
	CB_FUN handler;			//task handler
	struct task *next;		//task quene pointer
}threadpool_task_t;

//task queue
typedef struct task_queue
{
	threadpool_task_t *head;
	threadpool_task_t **tail;
	unsigned int cur_task_num;
}threadpool_task_queue_t;

//thread pool
typedef struct threadpool
{
	pthread_mutex_t mutex;
	pthread_cond_t cond;
	threadpool_task_queue_t tasks;

	unsigned int thread_num;
}threadpool_t;

//thread pool configuration
typedef struct threadpool_conf
{
	unsigned int thread_num;

}threadpool_conf_t;

threadpool_t *threadpool_init(threadpool_conf_t *conf);

int threadpool_add_task(threadpool_t *pool, CB_FUN handler, void *argv);

void threadpool_destroy(threadpool_t *pool);



#endif /* THREADPOOL_H_ */
<pre name="code" class="cpp">/*
 * threadpool.c
 *
 *  Created on: 2016年5月11日
 *      Author: qiangqaz
 */
#include "threadpool.h"

static 	pthread_key_t  key;

inline int threadpool_key_create()
{
	return pthread_key_create(&key, NULL);
}

inline void threadpool_key_destroy()
{
	pthread_key_delete(key);
}

int thread_conf_check(threadpool_conf_t *conf)
{
	if (NULL == conf)
	{
		printf("conf null\n");
		return -1;
	}

	if (conf->thread_num < 1)
	{
		printf("conf < 1\n");
		return -1;
	}

	return conf->thread_num;
}

void threadpool_task_queue_init(threadpool_task_queue_t *task_queue)
{
	task_queue->head = NULL;
	task_queue->tail = &task_queue->head;
}

int threadpool_mutex_create(pthread_mutex_t *mutex)
{
	int ret = 0;
	pthread_mutexattr_t attr;

	if (0 != pthread_mutexattr_init(&attr))
	{
		return -1;
	}

	if (0 != pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK))
	{
		pthread_mutexattr_destroy(&attr);
	}

	ret = pthread_mutex_init(&mutex, &attr);
	pthread_mutexattr_destroy(&attr);

	return ret;
}

void threadpool_mutex_destroy(pthread_mutex_t *mutex)
{
	pthread_mutex_destroy(mutex);
}

int threadpool_cond_create(pthread_cond_t *cond)
{
	return pthread_cond_init(cond, NULL);
}

void threadpool_cond_destroy(pthread_cond_t *cond)
{
	pthread_cond_destroy(cond);
}

void threadpool_cycle(void *argv)
{
	unsigned int exit_flag = 0;
	sigset_t set;
	threadpool_task_t *ptask = NULL;
	threadpool_t *pool = (threadpool_t*)argv;

	//只注册以下致命信号,其他全部屏蔽
	sigfillset(&set);
	sigdelset(&set, SIGILL);
	sigdelset(&set, SIGFPE);
	sigdelset(&set, SIGSEGV);
	sigdelset(&set, SIGBUS);

	if (pthread_setspecific(key,(void*)&exit_flag) != 0){//设置exit_flag = 0
		return;
	}
	if (pthread_sigmask(SIG_BLOCK, &set, NULL) != 0){
		return;
	}
	while(!exit_flag){         //exit_flag为1时线程退出
		if (pthread_mutex_lock(&pool->mutex) != 0){  //加锁
			return;
		}

		while(pool->tasks.head == NULL){
			if (pthread_cond_wait(&pool->cond, &pool->mutex) != 0){
				pthread_mutex_unlock(&pool->mutex);
				return;
			}
		}

		ptask = pool->tasks.head;     //从任务队列中获取一个任务任务节点
		pool->tasks.head = ptask->next;

		pool->tasks.cur_task_num--;   //当前任务数--

		if (pool->tasks.head == NULL){
			pool->tasks.tail = &pool->tasks.head;
		}

		if (pthread_mutex_unlock(&pool->mutex) != 0){ //解锁
			return;
		}

		ptask->handler(ptask->argv);  //执行任务。
		free(ptask);
		ptask = NULL;
	}
	pthread_exit(0);
}

int threadpool_create(threadpool_t *pool)
{
	pthread_t pid;
	pthread_attr_t attr;
	int i = 0;

	if (0 != pthread_attr_init(&attr))
	{
		return -1;
	}

	for (i = 0; i < pool->thread_num; i++)
	{
		pthread_create(&pid, &attr, threadpool_cycle, pool);
	}

	pthread_attr_destroy(&attr);
	return 0;
}


threadpool_t *threadpool_init(threadpool_conf_t *conf)
{
	threadpool_t *pool = NULL;

	do
	{
		if (thread_conf_check(conf) == -1)
		{
			printf("invalid thread conf!\n");
			break;
		}

		pool = (threadpool_t *)malloc(sizeof(threadpool_t));
		if (NULL == pool)
		{
			printf("thread pool malloc failed.\n");
			break;
		}

		pool->thread_num = conf->thread_num;
		pool->tasks.cur_task_num = 0;

		threadpool_task_queue_init(&pool->tasks);

		if (0 != threadpool_key_create())
		{
			printf("thread pool key create failed.\n");
			free(pool);
			break;
		}

		if (0 != threadpool_mutex_create(&pool->mutex))
		{
			printf("thread mutex create failed.\n");
			threadpool_key_destroy();
			free(pool);
			break;
		}

		if (0 != threadpool_cond_create(&pool->cond))
		{
			printf("thread cond create failed.\n");
			threadpool_key_destroy();
			threadpool_mutex_destroy(&pool->mutex);
			free(pool);
			break;
		}

		if (0 != threadpool_create(pool))
		{
			printf("thread pool create failed.\n");
			threadpool_key_destroy();
			threadpool_mutex_destroy(&pool->mutex);
			threadpool_cond_destroy(&pool->cond);
			free(pool);
			break;
		}

		return pool;

	}while (0);

	return NULL;
}

//向线程池中添加一个任务。handler为回掉函数,argv为参数
int threadpool_add_task(threadpool_t *pool, CB_FUN handler, void* argv)
{
	threadpool_task_t *task = NULL;
	int ret = 0;

	//申请一个任务节点并赋值
	task = (threadpool_task_t *)malloc(sizeof(threadpool_task_t));
	if (task == NULL)
	{
		printf("task null\n");
		return -1;
	}

	task->handler = handler;
	task->argv = argv;
	task->next = NULL;

	if ((ret = pthread_mutex_lock(&pool->mutex)) != 0)
	{
		printf("mutex lock failed. ret = %d\n",ret);
		//加锁
		free(task);
		return -1;
	}

	do
	{
		//将任务节点尾插到任务队列
		*(pool->tasks.tail) = task;
		pool->tasks.tail = &task->next;
		pool->tasks.cur_task_num++;

		//通知阻塞的线程
		if (pthread_cond_signal(&pool->cond) != 0){
			break;
		}
		//解锁
		pthread_mutex_unlock(&pool->mutex);
		return 0;

	}while(0);

	pthread_mutex_unlock(&pool->mutex);
	free(task);

	return -1;
}

//线程池退出函数
void threadpool_exit_cb(void* argv)
{
	unsigned int *lock = argv;
	unsigned int *pexit_flag = NULL;

	pexit_flag = (int *)pthread_getspecific(key);
	*pexit_flag = 1;    //将exit_flag置1
	pthread_setspecific(key, (void*)pexit_flag);
	*lock = 0;
}
//销毁线程池。
void threadpool_destroy(threadpool_t *pool)
{
	unsigned int n = 0;
	volatile unsigned int  lock;

	//z_threadpool_exit_cb函数会使对应线程退出
	for (; n < pool->thread_num; n++)
	{
		lock = 1;
		if (threadpool_add_task(pool, threadpool_exit_cb, &lock) != 0)
		{
			return;
		}
		while (lock)
		{
			usleep(1);
		}
	}

	threadpool_mutex_destroy(&pool->mutex);
	threadpool_cond_destroy(&pool->cond);
	threadpool_key_destroy();
	free(pool);
}


 

/*
 * main.c
 *
 *  Created on: 2016年5月11日
 *      Author: qiangqaz
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include "threadpool.h"

int testfun(void *argv)
{
	int *num = (int*)argv;
	printf("testfun thread_id = %u  num = %d\n",pthread_self(),*num);
	//sleep(3);
	return 0;
}

int main(int argc, char **argv)
{
	int array[10] = {0};
	int i = 0;
	threadpool_conf_t conf; //实例化启动参数
	conf.thread_num = 5;
	threadpool_t *pool = threadpool_init(&conf);//初始化线程池



	if (pool == NULL)
	{
		return 0;
	}

	for (; i < 10; i++){
		array[i] = i;
		while(1)
		{
			if (threadpool_add_task(pool, testfun, &array[i]) == 0)
			{
				break;
			}
			printf("error in i = %d\n",i);
			break;
		}
	}

	threadpool_destroy(pool);

	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值