博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
线程池的设计(一):半同步半异步线程池的设计
阅读量:6675 次
发布时间:2019-06-25

本文共 1112 字,大约阅读时间需要 3 分钟。

hot3.png

前置问答:

1.为什么要使用线程池? 避免大量创建和销毁线程,提升性能。

2.线程池主要工作流程?一是外部不断地向线程池添加任务,而是线程池内部不断地取任务执行,这是典型的生产者消费者模型。

3.线程池有几种类型?半同步半异步线程池 和 领导者追随者线程池。

第一部分:

半同步半异步线程池的工作流程:

代码实现:

1.启动:启动若干个线程,每个线程函数内部会循环从任务队列中取任务,任务队列的内容就是线程函数的函数名。

   要点:

   a. 线程函数是需要传给线程池对象的,线程池只负责管理线程,并不关心具体的工作线程的任务内容。

   b. 刚启动线程池,没有传入任何任务时,此时线程池内的所有工作者线程处于阻塞等待状态(使用条件变量和互斥量),等待任务的到来。使用while(m_running)进行循环等待,当m_running为false时即为线程池停止服务时。

2.添加任务:向线程池申请线程执行任务,线程池对象内部会想任务队列push一个任务。

   要点:

   a. 向任务队列push任务时,同步队列内部会通过条件变量唤醒正在阻塞的等待任务的工作者线程。

   条件变量的使用过程如下:

   ①. 拥有条件变量的线程获取互斥量;

   ②. 循环检查某个条件,如果条件不满足,则阻塞线程直到条件满足。如果条件满足,向下执行;

   ③. 某个线程满足条件执行完之后调用notify_one或notify_all唤醒一个或所有等待的线程;

   b.任务执行结束后,工作者线程继续陷入等待状态,直到下一个任务来临。

3.停止:等待所有线程结束后停止线程池。

   要点:

   a. 保证停止操作只能被调用一次,需要加锁;

   b. 将同步队列停止,这样同步队列就不再提供新的任务;

   c. 将线程池运行状态标示m_running置为停止状态,保证工作者线程函数不再等待新任务的到来;

   d. 等待所有工作者线程退出后,将线程池内创建好的线程组清空,释放资源;

关于半同步半异步线程池问答:

1.半同步半异步线程池如何构造的?主要分三层:同步服务层,任务队列,异步服务层。

2.任务队列为什么需要设置上限?同步任务队列如果不加上线控制,会导致排队任务过多,内存暴涨。

3.生产者过度生产任务时,有什么影响?任务被处理的等待时间会很长。

参考文档:

《C++11并发指南三(Lock详解)》 

《四种windows多线程通信方式》

《生产者消费者问题》 

《领导者跟随者模式》 

《高性能IO设计模式概述》 

期待下一篇:线程池的设计(二):领导者追随者线程池的设计

转帖请标明出自:

转载于:https://my.oschina.net/justfairytale/blog/654749

你可能感兴趣的文章
Python的可视化图表工具集
查看>>
《条目二十九:对于逐个字符的输入请考虑istreambuf_iterator》
查看>>
三个文件,
查看>>
webpack的总结
查看>>
hibernate 一级缓存和二级缓存
查看>>
javac不是内部或外部命令
查看>>
mvc SelectList selected失效的解决方法
查看>>
JAVA 设计模式 中介者模式
查看>>
我的软件工程课目标
查看>>
var a={n:1}; var b=a; a.x=a={n:2}; console.log(a.x); console.log(b.x);
查看>>
【HDOJ】3016 Man Down
查看>>
window.open打开新页面,并将本页数据用过url传递到打开的页面;需要两个页面;...
查看>>
查看本机IP分为两种情况:
查看>>
Scala进阶之路-Scala特征类与unapply反向抽取
查看>>
洛谷P3057 [USACO12NOV]远处的牧场Distant Pastures
查看>>
hdu3415 Max Sum of Max-K-sub-sequence 单调队列
查看>>
6421B Lab2 DHCP的配置及故障排除
查看>>
[C# 基础知识梳理系列]专题一:深入解析委托——C#中为什么要引入委托
查看>>
FOSCommentBundle功能包:其它添加评论到页面的方法
查看>>
Exchange 2016共享邮箱不保存已发送邮件的问题
查看>>