手搓线程池


为什么需要线程池?

一个管理和维持固定数量线程的池式结构,就是一个基础组件;在业务层调用结构基础组件的接口即可;
池式结构:避免重复的创建和销毁线程,实现线程的复用,减少资源的消耗;
1、当某类任务特别耗时,耗时任务异步抛到其他线程执行,解放核心线程的处理能力;

一个监听线程用来监听客户端请求,当存在多个客户端同时进行连接时,当这些请求比较耗时的时候,为了不阻塞监听线程,就将每个客户端连接放到一个新的工作线程中,
通常有两类耗时操作

1、耗时等待:比如需要通过系统调用来操作系统资源(系统资源用户态不能直接操作),例如网络资源、文件资源;我们在用户态通过系统调用到内核态,而在这个系统调用的过程中,涉及到用户态到内核态的切换,就要保存运行线程的现场,这是一个耗时的操作,第二,从内核态需要等待操作系统将资源准备就绪,再返回给用户态,这也是一个耗时的操作,涉及到IO操作,需要耗时等待,需要阻塞当前线程等待
2、耗时计算:某一个算法比较复杂,步骤费时,业务计算耗时,将它丢到另一个线程中去处理;

2.充分利用多核,提高并发能力;更大限度的利用系统资源;
异步执行:将当前线程的任务丢到其他线层去处理,不在当前线程处理

注意,需要将耗时操作抽象成具体的任务
C语言:通过结构体,实现一个回调函数,还需要上下文传递(上下文包装,比如某个参数)
C++:可以用函数对象、还可以用lambda,还可以用std::bind,还可以用一个结构体内的operator()实现一个操作符;

作用:

1、复用线程资源
2、充分利用系统资源
3、异步执行耗时任务

线程池线程数量如何确定?

线程是通过当前机器的核心数来驱动的,每个线程的执行占据一个核心;如果线程数量大于核心数的话,多余的部分线程其实是在等待的,并不能提升效率,还会引起线程切换引起的资源消耗;
什么类型的任务?

计算耗时的任务:CPU密集型

这种情况线程池数量一般设置为当前机器的核心数;

IO耗时的任务:IO密集型

通常设置为2倍的CPU核心数;

一般以上面所说的经验数量为基准进行试探,比如我们当前机器核心数为8,任务为CPU密集型,那我将从8个线程数量开始试探此时运行效率,然后9/10/7个线程数量,最后选择一个最优的运行效率的线程数量;针对IO密集型的试探也是一样的;这就是压力测试。

线程池的构成部分:

1、生产者线程:并不一定是线程池的构成部分,可能是业务的核心线程(监听线程),也可能是线程池中的构成部分,这是生产任务的线程;
2、线程池线程(消费者线程):是消费异步任务的线程;
3、线程池线程一般处于阻塞(休眠)状态(无任务时),
4、一种数据结构能够运行在多线程运行环境(加锁),要能快速够判断内部是否有任务;我们选择队列,队列是双开口的,生产者线程从一端push,消费者线程从一端pop;而且我们要确保在push和pop的时候要够快,够快线程占据锁的时间越短,线程池并发度就越高;队列的话,我们就是取一个节点,内部具体是链表连接起来的,非常快;(任务是通过链表连接起来的,是插入有序的,内部还有两个指针head和tail,当push指针的时候,只需要tail指针移动一位,尾节点连接上就可;),还能够快速地判断是否有任务,这决定了线程池是活跃的还是休眠的
在这里插入图片描述

实现线程池

线程池是一个基础组件,需要提供接口,不关心内部设计;用户通过一个thrdpool_create函数得到一个线程池类型指针,无需了解内部;
用户需要知道:

任务以什么样的形式执行:返回值为void类型,上下文为void*传递进去;

typedef void (*handler_pt)(void *);

创建线程池接口,关闭线程池接口

thrdpool_t *thrdpool_create(int thrd_count); void thrdpool_terminate(thrdpool_t * pool);

往线程池中抛一个任务

int thrdpool_post(thrdpool_t *pool, handler_pt func, void *arg);

优雅的退出:等待线程池中所有线程执行完毕

void thrdpool_waitdone(thrdpool_t *pool);

线程池对称式接口设计;

  • 11
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值