C语言
您现在所在的位置:首页>企业动态>C语言

来手把手教你,用C语言实现一个简单的线程池

编辑:学到牛牛IT培训    发布日期: 2022-09-30 16:30:50  

线程池主要是用于解决多线程使用时由于线程频繁创建销毁带来的性能损耗导致的实时性降低问题,例如我们常见的订单处理、Web服务器及数据库服务器等经常需要同时处理大量链接请求,并且单个任务本身处理时间较短,此时若采用使用时创建,结束时销毁的方式就会由于频繁的创建及销毁带来很多不必要的开销,这时就可以利用线程池统一进行任务分配及线程的创建销毁管理,线程池可以预先创建一定数量的线程,当没有足够数量的任务需要处理时多余的线程就处于阻塞状态无需占用CPU,等任务处理完毕后再进行线程的销毁,这样处理这种短暂任务就可以不需要频繁的去创建销毁线程,从而解决问题。


但如果是本身任务不多、耗时长且任务实时性要求不高的情况(此时线程创建销毁带来的耗时相比任务时间可以忽略)反而可能会因为线程池本身的开销带来性能降低如文件传输这种可能耗时较长的就不一定适合使用线程池,反而传统的即时创建,即时销毁可能会是更好的选择。

线程池主要由管理线程、工作线程及任务队列构成;任务队列用于存放暂未处理的任务,相当于任务排队等待调度执行,工作线程用于执行分配的任务,若未分配到任务则阻塞等待;管理线程用于创建、启动、停止、销毁线程及任务分配,起到管理线程池的作用。

线程池的原理就好比现在的XX打车,打车软件平台服务器就相当于管理线程、运输车辆就好比工作线程、每天的运输订单就相当于任务,订单一时可能过多就需要排队等待接单,排队的订单就相当于任务队列。平台就负责管理运营车辆及订单任务的分配,运输车辆负责完成订单任务,订单任务暂时没有车辆可安排则放入等待队列。

图片


编程实现线程池就是围绕上面的内容完成的,任务队列可以选择使用队列、链表或者数组实现,为了防止类似不同车辆抢到同一订单即多个线程抢到同一任务的情况我们会使用到互斥锁,车辆等待订单及执行订单(线程空闲等待及执行)则可使用条件变量。理想状态是订单有多少车辆就有多少,那我们就可以同时完成多个订单,但现实是订单太多可能平台可能会因为链接过多崩溃类似以前的12306购票系统,在线程池中也就是内存溢出(OOM)没有足够的内存存放所有等待的订单;同样我们的车辆(线程数)也不能无限多,就好比城市道路若道路上跑满了汽车,那也就会导致交通瘫痪汽车移动缓慢甚至无法移动(工作线程数过多CPU就会100%负载这样就可能出现整个系统运行缓慢甚至卡死)。

下面是C语言中线程、互斥锁及条件变量使用的相关函数,编写线程池就会用到这些函数接口:

1.线程操作函数

图片

2.互斥锁与条件变量相关函数

图片

图片

下面是模拟实现线程池的代码

图片
图片
图片

/*
 工作线程
 主要功能:
 *  1.等待队列任务
 *  2.结束多余线程(多余工作任务的线程及,线程池所有任务结束时的线程)
 *  3.从队列中获取并执行任务
 *  4.统计忙碌线程数
 */

图片

图片

图片
图片

图片






/*
 管理线程
 主要功能:
 *  1.当线程池中工作线程数不够时增加一定数量的线程
 *  2.当线程池中空闲工作线程数过多时通知闲置工作线程退出,让出资源
 */

图片

图片

图片

图片

图片

图片



//线程池初始化创建函数,可设定最小和最大线程数及最大队列大小

图片

图片
图片
图片









//线程池销毁函数  

图片
图片
   
//向线程池中增加任务的函数,work为需添加的任务,arg为任务可能需要的参数

图片
图片








这里用求一个较大数是否是质数来模拟线程耗时工作任务,下面是测试任务函数及主函数

图片

图片

图片

图片




下面为线程池任务工作效果


图片图片 

通过运行效果我们可以看出在前期我们线程池中由于任务过多会逐渐创建新的线程,当空闲线程过多时退出空闲线程,就达成了自动管理线程的效果。

下图是为了方便更改原理图使用与文章内容无关

图片


免费试学
课程好不好,不如实地听一听

封闭学习

2

1

联系我们

电话:028-61775817

邮箱:1572396657@qq.com

地址:成都市金牛区西城国际A座8楼

  • 扫一扫,免费咨询

  • 微信公众号

学一流技术,找高薪工作

7-24小时服务热线:

028-61775817

版权声明 网站地图

蜀ICP备2021001672号

课程问题轻松问