简单实现thread pool

网上看得代码,两个小时时间改进一下源代码,增加log机制:http://blog.csdn.net/zzran/article/details/42779851

#ifndef __thread_pool_h__
#define __thread_pool_h__

#include <pthread.h>

typedef struct work_s {
	void*          (*routine)(void*);
	void*          args;
	struct work_s* next;
}work_t;

typedef struct thread_pool_s {
	int              shutdown;
	int              max_thr_num;
	work_t*          queue_head;
	pthread_t*       thr_ids;
	pthread_mutex_t mutex;
	pthread_cond_t  cond;
}thread_pool_t;

int thread_pool_init(int max_thr_num);

void thread_pool_destroy();

int thread_pool_add(void*(*routine)(void*), void* args);

#endif



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


#include "log.h"
#include "thread_pool.h"

static thread_pool_t* tpool;

static void* thread_routine(void* args);

int thread_pool_init(int max_thr_num) {
	int i;
	int cond_inited = 0;
	int mutex_inited = 0;
	if (0 >= max_thr_num) {
		TRACE_ERROR("thread_pool_init(): max_thr_num <= 0.");
		return -1;
	}
	tpool = (thread_pool_t*)calloc(1, sizeof(thread_pool_t));
	if (NULL == tpool)
		goto err;
	tpool->shutdown = 0;
	tpool->max_thr_num = max_thr_num;
	tpool->queue_head = NULL;
	if (0 != pthread_mutex_init(&tpool->mutex, NULL)) {
		TRACE_ERROR("thread_pool_init(): init mutext, errno: %d, error:%s", errno, strerror(errno));
		goto err;
	} else {
		mutex_inited = 1;
	}
	if (0 != pthread_cond_init(&tpool->cond, NULL)) {
		TRACE_ERROR("thread_pool_init(): init cond, errno: %d, error:%s", errno, strerror(errno));
		goto err;
	} else {
		cond_inited = 1;
	}
	tpool->thr_ids = (pthread_t*)calloc(max_thr_num, sizeof(pthread_t));
	if (NULL == tpool->thr_ids) {
		TRACE_ERROR("thread_pool_init(): create threads error.");
		goto err;
	}
	for (i = 0; i < max_thr_num; i++) {
		if (0 != pthread_create(&tpool->thr_ids[i], NULL, thread_routine, NULL)) {
			TRACE_ERROR("thread_pool_init(): create thread %d error.", i);
			goto err;
		}
	}
	goto end;
err:
	if (tpool) {
		if (mutex_inited) 
			pthread_mutex_destroy(&tpool->mutex);
		if (cond_inited)
			pthread_cond_destroy(&tpool->cond);
		if (NULL != tpool->thr_ids) {
			free(tpool->thr_ids);
		}
		free(tpool);
	}
end:
	TRACE_DEBUG("thread_pool_init(): init pool successful.");
	return 0;
}

static void* thread_routine(void* arg) {
	work_t* work = NULL;

	while (1) {
		pthread_mutex_lock(&tpool->mutex);
		while (!tpool->shutdown && NULL == tpool->queue_head) {
			pthread_cond_wait(&tpool->cond, &tpool->mutex);
		}
		if (tpool->shutdown) {
			TRACE_DEBUG("thread_routine():thread pool shutdown.");
			pthread_mutex_unlock(&tpool->mutex);
			pthread_exit(NULL);
		}
		work = tpool->queue_head;
		tpool->queue_head = tpool->queue_head->next;
		pthread_mutex_unlock(&tpool->mutex);

		work->routine(work->args);
		free(work);
	}
	return NULL;
}

void thread_pool_destroy() {
	int i;
	work_t* work = NULL;
	if (tpool->shutdown) {
		TRACE_DEBUG("thread_pool_destroy(): already shutdown.");
		return;
	}
	tpool->shutdown = 1;
	pthread_mutex_lock(&tpool->mutex);
	pthread_cond_broadcast(&tpool->cond);
	pthread_mutex_unlock(&tpool->mutex);
	for (i = 0; i < tpool->max_thr_num; i++) {
		TRACE_DEBUG("thread_pool_destroy(): thread %d finish.", i);
		pthread_join(tpool->thr_ids[i], NULL);
	}
	free(tpool->thr_ids);
	while (tpool->queue_head) {
		work = tpool->queue_head;
		tpool->queue_head = tpool->queue_head->next;
		free(work);
	}
	pthread_mutex_destroy(&tpool->mutex);
	pthread_cond_destroy(&tpool->cond);
	free(tpool);
	tpool = NULL;
}

int thread_pool_add(void*(*routine)(void*), void* args) {
	work_t* work, *node;
	if (NULL == routine) {
		TRACE_ERROR("thread_pool_add(): no routine.");
		return 0;
	}
	work = (work_t*)calloc(1, sizeof(work_t));
	if (NULL == work) {
		TRACE_ERROR("thread_pool_add(): calloc failed.");
		return 0;
	}
	work->routine = routine;
	work->args = args;
	pthread_mutex_lock(&tpool->mutex);
	if (NULL == tpool->queue_head) {
		tpool->queue_head = work;
	} else {
		node = tpool->queue_head;
		while (node->next) {
			node = node->next;
		}
		node->next = work;
	}
	pthread_cond_signal(&tpool->cond);
	pthread_mutex_unlock(&tpool->mutex);
	return 0;
}

测试代码:

#include <stdio.h>
#include <unistd.h>

#include "log.h"
#include "thread_pool.h"

void *func(void *arg) {
	TRACE_INFO("thread %d working", (int)arg);
	return NULL;
}

int main(int argc, char* argv[]) {
	set_log_path("/Users/zzran/c-program/thread_test/l");
	TRACE_DEBUG("main():");
	if (0 != thread_pool_init(5)) {
		TRACE_ERROR("main(): thread pool init failed.");
		return 0;
	}
	int i;
	for (i = 0; i < 10; ++i) {
	    thread_pool_add(func, (void*)i);
	}
	sleep(2);
	thread_pool_destroy();
	return 0;	
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值