linux高性能服务器-线程池实现

本文详细介绍了线程池的概念、应用场景,以及如何通过数据结构如链表和队列设计来管理和调度任务。涉及CPU密集型和IO密集型任务,讨论了线程数量的选择,以及使用自旋锁和互斥锁进行同步控制。最后概述了线程池的创建、任务添加和线程终止过程。

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

定义

线程池属于生产消费模型,管理维持固定数量线程的池式结构,避免线程频繁的创建和销毁

应用场景

当一类任务耗时,严重影响当前线程处理其他任务,异步执行

任务类型

耗时任务:

  • CPU密集型
  • IO密集型 ( 网络IO 磁盘IO)
线程数量

n * proc

数据结构设计:
任务设计:
typedef struct task_s {
   
   
	void * next;
	handler_pt func;
	void * arg;
} task_t;

生产者线程: 发布任务
消费者线程: 取出任务,执行任务
数据结构为链表

队列设计:

typedef struct task_queue_s {
   
   
	void * head;
	void **tail;
	int block; // 是否阻塞 
	spinlock_t lock; // 自选锁
	pthread_muxtex_t mutex;
	pthread_cond_t cond;
}task_queue_t;

队列: 存储任务,调度线程池 ,双端开口,先进先出,在多线程中执行,需要加锁
功能: 调取线程池中的消费者线程, 如果此时队列为空,谁(线程)来取任务,谁阻塞休眠
当允许一个进程进入临界资源(互斥状态)。
自旋锁: 其他线程空转cpu,一直等待进入临界资源
互斥锁:切换cpu, 让出执行权, 线程阻塞住,操作系统调用其他的线程

某个线程持有临界资源的时间 < 线程切换的时间 , 自旋锁 ,时间复杂度为0(1)
生产者新增任务,消费者取出任务 ,0(1),均为移动指针完成(尾插法,头插法)
故使用自旋锁 spinlock_t lock

线程池设计
struct thredpool_t {
   
   
	atomic_int quit;  // 原子变量
	int thrd_count;
	pthread_t * threads;
	task_queue_t task_queue;
};

原子操作:一个线程在执行过程中,其他线程不能执行这个线程的内部操作,只能看到线程执行前或者执行后
应用场景: 某一个基础类型给的变量

接口设计
static task_queue_t * __taksqueue_create() {
   
   
	task_queue_t  * queue = malloc(sizeof(*queue));
	int ret;
	ret = pthrad_mutex_init(&mutex);
	if(ret == 0) {
   
   
		ret = pthread_cond_init(&cond);
		if(ret == 0) {
   
   
			queue->head = NULL;
			queue->tail = &(queue->head);
			queue->block = 1;
			return queue;
		}
		pthread_cond_destory(&queue);
	}
	pthread_muext_destory(&queue->mutex);
	return NULL;
}

static void __add_task(task_queue_t  * queue, void * task) {
   
   
	void **link = (void **
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

八月的雨季997

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值