线程池实现

线程池实现(队列链表实现)

1、避免线程太多,是的内存耗尽
2、避免创建与销毁线程的代价

基本结构体

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
struct nTask {  //任务的结构体
	void (*task_func)(struct nTask *task); // 任务执行的函数
	void *user_data;    // 任务执行函数的入参

	struct nTask *prev; // 上节点任务
	struct nTask *next; // 下节点任务
};

struct nWorker {  // 工作空间
	pthread_t threadid;  // 线程id
	int terminate;  // 线程是否退出
	struct nManager *manager;

	struct nWorker *prev;
	struct nWorker *next;
};

// 管理线程池的结构体
typedef struct nManager {
	struct nTask *tasks;  //任务链表
	struct nWorker *workers;    // 工作空间

	pthread_mutex_t mutex;  // 线程池的锁
	pthread_cond_t cond;    // 条件变量
} ThreadPool;

链表操作宏定义

#define LIST_INSERT(item, list) do {	\
	item->prev = NULL;					\
	item->next = list;					\
	if ((list) != NULL) (list)->prev = item; \
	(list) = item;						\
} while(0)
#define LIST_REMOVE(item, list) do {	\
	if (item->prev != NULL) item->prev->next = item->next; \
	if (item->next != NULL) item->next->prev = item->prev; \
	if (list == item) list = item->next; 					\
	item->prev = item->next = NULL;							\
} while(0)

线程池的创建

int nThreadPoolCreate(ThreadPool *pool, int numWorkers) {

	if (pool == NULL) return -1;
	if (numWorkers < 1) numWorkers = 1;
	memset(pool, 0, sizeof(ThreadPool));
	//初始化线程池的条件变量
	pthread_cond_t blank_cond = PTHREAD_COND_INITIALIZER;
	memcpy(&pool->cond, &blank_cond, sizeof(pthread_cond_t));

	// 初始化线程池的锁
	pthread_mutex_t blank_mutex = PTHREAD_MUTEX_INITIALIZER;
	memcpy(&pool->mutex, &blank_mutex, sizeof(pthread_mutex_t));
	

	//创建工作空间
	int i = 0;
	for (i = 0;i < numWorkers;i ++) {
		struct nWorker *worker = (struct nWorker*)malloc(sizeof(struct nWorker));
		if (worker == NULL) {
			perror("malloc");
			return -2;
		}
		memset(worker, 0, sizeof(struct nWorker));
		worker->manager = pool; //
        // 创建线程 参数1: 线程的指针,参数 2:线程属性,参数三:线程运行的函数,参数4:运行的函数传递的参数
		int ret = pthread_create(&worker->threadid, NULL, nThreadPoolCallback, worker);
		if (ret) {
			perror("pthread_create");
			free(worker);
			return -3;
		}
		// 将工作空间插入链表中。。。
		LIST_INSERT(worker, pool->workers);
	}

	// success
	return 0; 

}

线程执行的函数

// callback != task 线程的函数
static void *nThreadPoolCallback(void *arg) {

	struct nWorker *worker = (struct nWorker*)arg;

	while (1) {  // 尝试获取任务
        // 加线程池锁  
		pthread_mutex_lock(&worker->manager->mutex);

		while (worker->manager->tasks == NULL) {  // 如果当前tasks中没有任务
			if (worker->terminate) break;
			pthread_cond_wait(&worker->manager->cond, &worker->manager->mutex); // 没有任务阻塞等待
		}

		if (worker->terminate) {  // 线程销毁 时候会触发
			pthread_mutex_unlock(&worker->manager->mutex);
			break;
		}

		// 有任务
		// 获取到任务task
		struct nTask *task = worker->manager->tasks;
		// 将任务task 从链表中删掉
		LIST_REMOVE(task, worker->manager->tasks);
        // 释放线程池锁
		pthread_mutex_unlock(&worker->manager->mutex);
        // 调用 任务函数
		task->task_func(task);
	}
	free(worker); // 释放空间
	
}

线程池销毁 函数

int nThreadPoolDestory(ThreadPool *pool, int nWorker) {

	struct nWorker *worker = NULL;

	for (worker = pool->workers;worker != NULL;worker = worker->next) {
		worker->terminate;  //  将 线程池的terminate 全部设置为 1
	}
    // 加锁
	pthread_mutex_lock(&pool->mutex);

	pthread_cond_broadcast(&pool->cond);  // 牛逼牛逼   唤醒所有线程

	// 解锁
	pthread_mutex_unlock(&pool->mutex);

	// 置NULL
	pool->workers = NULL;
	pool->tasks = NULL;

	return 0;
	
}

线程池添加任务

// 任务放入到线程池中
int nThreadPoolPushTask(ThreadPool *pool, struct nTask *task) {

    // 将线程池中的互斥锁 加锁
	pthread_mutex_lock(&pool->mutex);
    // 将任务插入到链表
	LIST_INSERT(task, pool->tasks);
    //唤醒某一个线程开始  执行任务
	pthread_cond_signal(&pool->cond);

	// 将线程池中的互斥锁 解锁
	pthread_mutex_unlock(&pool->mutex);

}

测试


#if 1

#define THREADPOOL_INIT_COUNT	20
#define TASK_INIT_SIZE			1000


void task_entry(struct nTask *task) { //type 

	//struct nTask *task = (struct nTask*)task;
	int idx = *(int *)task->user_data;

	printf("idx: %d\n", idx);

	free(task->user_data);
	free(task);
}


int main(void) {

	ThreadPool pool = {0};
	
	nThreadPoolCreate(&pool, THREADPOOL_INIT_COUNT);
	// pool --> memset();
	
	int i = 0;
	for (i = 0;i < TASK_INIT_SIZE;i ++) {
		struct nTask *task = (struct nTask *)malloc(sizeof(struct nTask));
		if (task == NULL) {
			perror("malloc");
			exit(1);
		}
		memset(task, 0, sizeof(struct nTask));

		task->task_func = task_entry;
		task->user_data = malloc(sizeof(int));
		*(int*)task->user_data  = i;

		nThreadPoolPushTask(&pool, task);
	}

	getchar();  // 等待子线程运行完成
	
}


#endif


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值