Linux下使用C语言实现线程池---代码及分析

本文介绍了线程池在服务器中的应用,通过创建固定数量的线程来处理客户端连接,利用条件变量实现线程阻塞和唤醒,同时根据连接数量动态调整线程池大小,提高并发处理效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

线程池

相关文章
协议
Socket编程
高并发服务器实现
线程池

如果一个客户端建立连接使用创建一个线程用于处理这一个线程, 处理结束的时候把这一个线程删除, 这个时候会导致线程的创建以及销毁会消耗大量的时间

这时候可以一次性创建多个线程, 这几个线程统称线程池, 如果客户端建立一个连接, 线程池分配一个线程处理客户发过来的数据, 不处理的时候这几个线程阻塞

可以使用条件变量进行阻塞

线程的数量可以随着连接的个数, 时间等条件进行变换, 但是要有一个上限, 连接分个数增加的时候加线程, 如果忙的线程数量比较少的时候释放线程, 这一些处理使用一个adjust线程进行处理

img

实际实现

主函数

  • 创建一个线程池
  • 在里面添加任务
  • 等待
  • 关闭线程池

线程池

  • 初始化各种数据

  • 获取基础线程, 让他们阻塞等待任务

  • 获取任务, 唤醒线程处理

  • 处理结束接着阻塞

    后台的控制线程(adjust_thread)根据线程的实际使用情况添加或者释放线程

/*************************************************************************
    > File Name: thread_pool.c
    > Author: XvSenfeng
    > Mail: 1458612070@qq.com 
    > Created Time: Wed 10 Apr 2024 08:23:27 PM CST
 ************************************************************************/

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

使用的头文件


//多长时间判断一下是否需要增加获取减少线程个数
//这一个值小一点看现象
#define DEFAULT_TIME	3
//最小的执行的线程的个数
#define MIN_WAIT_TASK_NUM	10
//增加减少的时候步长
#define DEFAULT_THREAD_VARY	10
#define true 1
#define false 0

使用的宏定义

//记录一个回调函数, 由于线程执行
typedef struct {
   
	void *(*function)(void *);
	void *arg;
} threadpool_task_t;

//线程池的控制结构体
typedef struct{
   
	pthread_mutex_t lock;				//这一个结构体使用
	pthread_mutex_t thread_counter;		//记录忙状态的线程的个数
	
	pthread_cond_t queue_not_full;		//队列,没有满的时候添加使用
	pthread_cond_t queue_not_empty;

	pthread_t *threads;					//线程数组, 记录现在使用的线程的pid
	pthread_t adjust_tid;				//管理者的id
	threadpool_task_t *task_queue;		//线程执行任务的时候使用的环形队列

	int min_thr_num;			//最小的时候保留的线程个数
	int max_thr_num;			//最大可以支持的个数
	int live_thr_num;			//存活的线程的个数
	int busy_thr_num;			//执行任务的线程的个数
	int wait_exit_thr_num;		//需要释放的线程的个数
	//队列使用
	int queue_front;
	int queue_rear;
	int queue_size;
	int queue_max_size;

	int shutdown;			//记录这一个线程池有没有使用


}threadpool_t; 

线程池的控制结构体, 以及任务信息记录的结构体

void *adjust_thread(void *threadpool);
void threadpool_free(threadpool_t *pool);
//普通的线程处理函数
void *threadpool_thread(void *threadpool){
   
	threadpool_t *pool = (threadpool_t *)threadpool;
	threadpool_task_t task;

	while(true){
   
		pthread_mutex_lock(&(pool->lock));
		//判断一下现在没有可以执行的任务, 并且这一个线程组还没有销毁
		while((pool->queue_size == 0) && (!pool->shutdown)){
   
			printf("thread %#x is waiting\n", (unsigned int)pthread_self());
			//等待任务, 获取清除唤醒
             pthread_cond_wait(&pool->queue_not_empty, &pool->lock);
			//需要清除一部分线程
			if(pool->wait_exit_thr_num > 0){
   
				pool->wait_exit_thr_num--;//记录需要清除的任务的个数
				if(pool->live_thr_num > pool->min_thr_num){
   
					printf("thread %#x is exiting\n", (unsigned int)pthread_self());
					pool->live_thr_num--;
					pthread_mutex_unlock(&pool->lock);
					pthread_exit(NULL);
				}
			}
		}
		//这时候是有待处理的任务, 或者这一个线程池被销毁了
		
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值