C语言实现一个简单的线程池

原创 2013年12月05日 00:37:48

(代码有参考网上的一些实现)还有几个功能需要慢慢的实现和一些bug需要改,比如实现线程池的动态增长:

详细请看我的github: https://github.com/chengshuguang/thread-pool


thread_pool.h

#ifndef THREAD_POOL_H
#define THREAD_POOL_H

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

typedef struct task
{
	void *(*taskfunc)(void *arg);//声明一个函数指针
	void *arg;//函数的参数
	struct task *next;
}task;

typedef struct thread_pool
{
	task *task_queue_head;//任务队列
	task *task_queue_end;//指向任务队列结尾
	int task_queue_size;

	pthread_t *thread_queue;//线程队列
	int thread_num;
	int idle_thread_num;//空闲线程数

	int is_pool_destroyed;

	pthread_mutex_t queue_mutex;//用来互斥访问任务队列
	pthread_cond_t queue_cond;
}thread_pool;


#ifdef __cplusplus
extern "C"{
#endif

extern thread_pool *pool;
extern int thread_pool_init(int thread_pool_size);
//extern void * thread_pool_entrance(void *arg);
extern int thread_pool_add_task(void *(*taskfunc)(void *arg), void *arg);
extern int thread_pool_destroy();

#ifdef __cplusplus
}
#endif

#endif //THREAD_POOL_H

thread_pool.c

#include "thread_pool.h"
#include <pthread.h>
thread_pool *pool = NULL;
void * thread_pool_entrance(void *arg)
{
	int thread_id = (int)arg;
	printf("thread %d is created\n",thread_id);

	while(1)
	{
		pthread_mutex_lock(&(pool->queue_mutex));
		while(pool->task_queue_size == 0 && !pool->is_pool_destroyed)//必须用while,防止假唤醒
		{
			pthread_cond_wait(&(pool->queue_cond),&(pool->queue_mutex));//等待的时候会解锁,唤醒后加锁
		}

		if(pool->is_pool_destroyed)
		{
			printf("thread %d exit!!!\n",thread_id);
			pthread_mutex_unlock(&(pool->queue_mutex));//中途退出最容易出错,注意要解锁
			pthread_exit(NULL);
		}

		pool->idle_thread_num--;//线程进入忙碌状态
		//从任务队列中取出任务
		task *work;
		work = pool->task_queue_head;
		pool->task_queue_head = pool->task_queue_head->next;
		if(pool->task_queue_head == NULL)
			pool->task_queue_end = NULL;

		pool->task_queue_size--;

		pthread_mutex_unlock(&(pool->queue_mutex));

		//回调函数
		(*(work->taskfunc))(work->arg);
		pool->idle_thread_num++;//线程空闲
	}
	return NULL;
}


int thread_pool_init(int thread_pool_size)
{
	pool = (thread_pool *)malloc(sizeof(thread_pool));//不要最先给线程池分配空间

	pool->is_pool_destroyed = 0;

	pool->task_queue_head = NULL;
	pool->task_queue_end = NULL;
	pool->task_queue_size = 0;

	pool->thread_num = thread_pool_size;
	pool->thread_queue = (pthread_t *)malloc(thread_pool_size * sizeof(pthread_t));
	pool->idle_thread_num = thread_pool_size;

	//创建线程
	int i, ret;
	for(i=0; i<thread_pool_size; i++)
	{
		ret = pthread_create(&(pool->thread_queue[i]), NULL, thread_pool_entrance, (void *)i);
		if(ret < 0)
		{
			printf("thread create error!!!\n");
			thread_pool_destroy();//注意销毁,避免内存泄漏
			return -1;
		}
	}

	pthread_mutex_init(&(pool->queue_mutex), NULL);
	pthread_cond_init(&(pool->queue_cond), NULL);

	return 0;
}


typedef void *(*taskfunc)(void *arg);
int thread_pool_add_task(taskfunc func, void *arg)
{
	task *newtask;
	newtask = (task *)malloc(sizeof(task));
	newtask->taskfunc = func;
	newtask->arg = arg;
	newtask->next = NULL;

	pthread_mutex_lock(&(pool->queue_mutex));

	if(pool->task_queue_head == NULL)
	{
		pool->task_queue_head = pool->task_queue_end = newtask;
	}
	else
	{
		pool->task_queue_end = pool->task_queue_end->next = newtask;
	}
	pool->task_queue_size++;

	pthread_cond_signal(&(pool->queue_cond));
	pthread_mutex_unlock(&(pool->queue_mutex));

	return 0;
}


int thread_pool_destroy()
{
	if(pool->is_pool_destroyed)//防止多次销毁
		return -1;

	pool->is_pool_destroyed = 1;

	pthread_cond_broadcast(&(pool->queue_cond));//通知所有线程线程池销毁了
	int i;
	for(i=0; i<pool->thread_num; i++)//等待线程全部执行完
		pthread_join(pool->thread_queue[i], NULL);

	//销毁任务队列
	task *temp = NULL;
	while(pool->task_queue_head)
	{
		temp = pool->task_queue_head;
		pool->task_queue_head = pool->task_queue_head->next;
		free(temp);
	}
	//pool->task_queue_head = NULL;
	//pool->task_queue_end = NULL;

	//销毁线程队列
	free(pool->thread_queue);
	pool->thread_queue = NULL;

	pthread_mutex_destroy(&(pool->queue_mutex));
	pthread_cond_destroy(&(pool->queue_cond));

	free(pool);
	pool = NULL;

	return 0;
}

test.c

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

void *taskprocess(void *arg)
{
	printf("aaaaaadoing tasksaaaaaaaaa\n");
	usleep(1000);
	return NULL;
}


int main()
{
	thread_pool_init(5);
	int i;
	for(i=1; i<=10; i++)
	{
		thread_pool_add_task(taskprocess,(void *)i);
		usleep(1000);
	}
	sleep(1);
	thread_pool_destroy();
	return 0;
}


相关文章推荐

使用socket的Linux上的C语言helloworld多进程并发服务器

//使用socket的Linux上的C语言helloworld并发服务器////////////////////////////////////////////////////////////////...
  • dlutcat
  • dlutcat
  • 2007年10月07日 09:00
  • 3325

Linux网络编程-UDP数据阻塞接收超时设置

网络编程,linux,udp-socket,setsockopt,recvfrom

linux下用c语言实现一个简单的线程池

首先大家思考一个问题:为什么需要内存池? 我们知道应用程序创建一个对象,然后销毁对象是很耗费资源的。创建线程,销毁线程,也是如此。因此,我们就预先生成一些线程,等到我们使用的时候在进行调度,于是,一...

一个Linux下c语言线程池的实现

#include "threadpool.h" #include "common.h" threadpool_t *threadpool_init(int thread_num, int queue_...
  • tzshlyt
  • tzshlyt
  • 2017年07月06日 22:06
  • 181

【收集】Linux线程池(C语言)及简单实现示例

【收集】Linux线程池(C语言)及简单实现示例 1.线程池基本原理   在传统服务器结构中, 常是 有一个总的 监听线程监听有没有新的用户连接服务器, 每当有一个新的 用户进入, 服务器就开启一...

c语言线程池的简单实现

在某种CPU密集型的应用场景中,处理计算任务耗时较多(如图像处理),考虑多核CPU的优势,若能把计算分担到多个线程中处理则能有效利用CPU; 但是,若过开启过多的线程,线程创建销毁、线程间切换所带来的...

Linux 下C语言简单实现线程池

C语言简单实现线程池 0 前言 网上关于线程池的例子还是不少,简单明了的倒是比较少,看了网上的资料,打算借鉴网上的一些例子,自己实现以下。 线程的概念就不多说,首先说一下多线程的好处:多线程技...

线程池技术个人理解以及c语言的简单实现

这几天闲来无事,网上无意中看到了关于线程池的东西,发现挺有意思的,找了挺多资料,研究一下,线程池技术,个人理解,线程池是个集合(概念上的,当然是线程的集合),假设这个集合中有3个线程A , B, C ...
  • mxgsgtc
  • mxgsgtc
  • 2013年09月14日 22:06
  • 1889

C语言实现简单线程池

有时我们会需要大量线程来处理一些相互独立的任务,为了避免频繁的申请释放线程所带来的开销,我们可以使用线程池。下面是一个C语言实现的简单的线程池。 头文件: 1: #ifndef ...

嵌入式 C语言实现简单线程池

有时我们会需要大量线程来处理一些相互独立的任务,为了避免频繁的申请释放线程所带来的开销,我们可以使用线程池。下面是一个C语言实现的简单的线程池。 头文件: 1: #ifndef ...
  • skdkjxy
  • skdkjxy
  • 2014年06月30日 16:32
  • 575
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C语言实现一个简单的线程池
举报原因:
原因补充:

(最多只允许输入30个字)