线程池使用例子

//main.c文件
#include "test_pool.h"
#include <stdbool.h>
/*
	通过线程池来调用下面这3个任务函数
*/

void *eat(void *arg)
{
	printf("吃饭\n");
}

void *mysleep(void *arg)
{
	printf("睡觉\n");
}

void *play(void *arg)
{
	printf("打游戏\n");
}

int main(int argc,char **argv)
{
	int num =5;
	thread_pool *mypool = malloc(sizeof(struct pool));
	
	//初始化线程池(3条线程)	
	init_pool(mypool,num);//在初始化的时候创建了num条线程

	
	//添加了3个任务
	add_task(mypool,eat,NULL);
	add_task(mypool,mysleep,NULL);
	add_task(mypool,play,NULL);
	
	//按照实际情况来增加线程或者删除线程
	//add_thread();
	remove_thread(mypool,4);
	
	//销毁线程池
	destroy_pool(mypool);
	

	
	return 0;
}


//线程池的函数
#include "test_pool.h"
/*
xxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxx
xxxxxxxxxxxxxxxxxxxxxx
*/

//压栈的句柄函数
void handler(void *arg)
{
	//解锁
	thread_pool *pool = (thread_pool *)arg;
	pthread_mutex_unlock(&pool->lock);
	
}

//做任务的线程--删除任务节点
void *routine(void *arg)
{
	//1. 先接住线程池的地址
	thread_pool *pool = (thread_pool *)arg;
	struct task *p;

	while(1)
	{
		//2. 线程取消例程函数
		//将来要是有人要取消我,请先把锁解开,然后再响应取消。
		pthread_cleanup_push(handler,(void *)&pool->lock);
		
		//3. 上锁
		pthread_mutex_lock(&pool->lock);
		
		//如果当前线程池没有关闭,并且当前线程池没有任务做(有线程没有任务,池子是打开的)
		while(pool->waiting_task == 0 && !pool->shutdown)
		{
			//那么就进去条件变量中睡觉。
			pthread_cond_wait(&pool->cond, &pool->lock); //自动解锁
		}
		
		//要是线程池关闭了,或者有任务做,这些线程就会运行到这行代码
		//判断当前线程池是不是关闭了,并且没有等待的任务
		if(pool->waiting_task == 0 && pool->shutdown == true)
		{	
			//如果线程池关闭,又没有任务做
			//线程那么就会解锁
			pthread_mutex_unlock(&pool->lock);	
			
			//线程走人
			pthread_exit(NULL); 
		}
		
		//能运行到这里,说明有任务做  (删除节点)
		//p指向头节点的下一个
		p = pool->task_list->next;
		
		//让头节点的指针域指向p的下一个节点
		pool->task_list->next = p->next;
		
		//当前任务个数-1
		pool->waiting_task--;

		//解锁
		pthread_mutex_unlock(&pool->lock);
		
		//删除线程取消例程函数
		pthread_cleanup_pop(0);
		
		//设置线程不能响应取消
		pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); 
		
		//执行这个p节点指向的节点的函数(执行任务)
		(p->do_task)(p->arg);  //等价跑了代码 eat(NULL)
		
		//设置线程能响应取消
		pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);

		//释放p对应的空间
		free(p);
	}

	pthread_exit(NULL);
}
	


//线程池的初始化
bool init_pool(thread_pool *mypool_head,int threads_number)
{
	//初始化互斥锁
	pthread_mutex_init(&mypool_head->lock,NULL);
	//初始化条件变量
	pthread_cond_init(&mypool_head->cond,NULL);
	//初始化线程池开关量
	mypool_head->shutdown = false;

	//初始化线程池任务链表(单向链表)
	  //也就是初始化任务链表里面的链表头
	mypool_head->task_list = malloc(sizeof(struct task));

	//根据自定义的线程的数量创建线程
	  //使用for循环循环创建
	mypool_head->tids = malloc(sizeof(pthread_t)*ACT_PTHREAD_ID);
	if(mypool_head->task_list == NULL || mypool_head->tids == NULL)
	{
		perror("pthread_pool fail\n");
		return false;
	}

	mypool_head ->task_list ->next= NULL;
	mypool_head->max_waiting_task = MAX_PTHREAD_ID; 
	mypool_head->waiting_task = 0;
	mypool_head->active_threads = threads_number;
	int i;
	for(i = 0;i < mypool_head->active_threads;i++)
	{
		if(pthread_create(&((mypool_head->tids)[i]),NULL,routine,(void *)mypool_head) != 0)
		{
			perror("create threads error");
			return false;
		}
	}
	//返回链表的开关量  
	return true;
}

//添加任务节点
bool add_task(thread_pool *pool,void *(*do_task)(void *arg), void *arg)
{
	//新建任务链表的节点
	struct task *new_task = malloc(sizeof(struct task));
	new_task->do_task = do_task;
	new_task->arg = arg;
	new_task->next = NULL;
	
 	//上锁	
	pthread_mutex_lock(&pool->lock);
	
	if(pool->waiting_task >= MAX_PTHREAD_ID)
	{
		
		//释放新节点
		pthread_mutex_unlock(&pool->lock);
		printf("too many task.\n");
		free(new_task);
		return false;
		//解锁
		
	}

	struct task *tmp = pool->task_list;
	while(tmp->next != NULL)
	{
		tmp = tmp->next;
		
	}
	tmp->next = new_task;
	pool->waiting_task ++;
	pthread_mutex_unlock(&pool->lock);
	pthread_cond_signal(&pool->cond);
	return true;
}

//添加线程
int add_thread(thread_pool *pool, unsigned additional_threads)
{
	//如果添加的线程数为0
	if(additional_threads == 0)
		return 0;

	unsigned total_threads = pool->active_threads + additional_threads;
		
	int i,actual_increment = 0;	
	//创建线程
	for(i=pool->active_threads; i < total_threads && i < MAX_PTHREAD_ID;i++)
	{
		if(pthread_create(&((pool->tids)[i]),NULL,routine,(void*)pool)!=0)
		{
			perror("add threads error");
			if(actual_increment == 0) 
				return -1;

			break;
		}
		actual_increment++; 	
	}
	
	pool->active_threads += actual_increment;
	//返回实际的线程添加数
	return actual_increment;	
}

//删除线程
int remove_thread(thread_pool *pool, unsigned int removing_threads)
{
	//如果删除的线程数为0
	if(removing_threads == 0)
		return pool->active_threads;
	int i;
	int errno;
	//删除从最后面一个线程号开始删除
	
	int remaining_threads = pool->active_threads - removing_threads;
	remaining_threads = remaining_threads > 0 ? remaining_threads : 1; 
	for(i=pool->active_threads-1; i>remaining_threads-1; i--)
	{	
		errno = pthread_cancel(pool->tids[i]); //取消这些线程
		if(errno != 0)
			break;
	}

	if(i == pool->active_threads-1) //删除失败
		return -1;
	else
	{
		pool->active_threads = i+1; //当前实际线程个数
		return i+1; 
	}
	//返回还有多少个线程数	
}

bool destroy_pool(thread_pool *pool)
{
	//1. 设置线程池关闭标志为真
	pool->shutdown = true; 
	int errno;
	//广播
	pthread_cond_broadcast(&pool->cond);  //目的: 就是让线程退出!
	
	//2. 接合所有的线程
	int i;
	for(i=0; i<pool->active_threads; i++)
	{
		errno = pthread_join(pool->tids[i], NULL);  //阻塞等待所有的线程退出

		if(errno != 0)
		{
			printf("join tids[%d] error: %s\n",
					i, strerror(errno));
		}
	
		else
			printf("[%u] is joined\n", (unsigned)pool->tids[i]);
		
	}

	//3. 释放一些空间
	free(pool->task_list); //释放链表
	free(pool->tids); //释放线程数
	free(pool);//释放线程池

	return true;
}


//头文件
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <semaphore.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

//宏定义
#define   MAX_PTHREAD_ID   1024
#define   ACT_PTHREAD_ID   1024

//任务链表节点
struct task
{
    void *(*do_task)(void *arg);
    void *arg;
    struct task *next;
};

//线程池的结构体
typedef struct pool
{
    pthread_mutex_t lock;
    pthread_cond_t cond;
    bool shutdown;
    struct task *task_list;
    pthread_t *tids;
    unsigned max_waiting_task;
    
    unsigned waiting_task;
    unsigned active_threads;

}thread_pool;


void handler(void *arg);
void *routine(void *arg);
bool init_pool(thread_pool *mypool_head,int threads_number);
bool add_task(thread_pool *pool,void *(*do_task)(void *arg), void *arg);
int add_thread(thread_pool *pool, unsigned additional_threads);
int remove_thread(thread_pool *pool, unsigned int removing_threads);
bool destroy_pool(thread_pool *pool);
void handler(void *arg);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值