当前位置:网站首页>基于线程池的生产者消费者模型(含阻塞队列)
基于线程池的生产者消费者模型(含阻塞队列)
2022-07-03 02:11:00 【abs(ln(1+NaN))】
一、线程池
和内存池一样,线程池也是为了提升效率。一个服务器可能短时间会接收到很多请求,等接收到请求再创建线程,此时就需要先创建线程,这样就会降低处理速度。

为了应对这种情况,我们一般会提前创建好一批线程,降低了短时间内创建和销毁线程的成本。就好比你要去火锅店吃火锅,店家不会等你来了再去屠宰场取肉,肯定会先把肉准备好。

二、模型实现
现在我们要建立这样一个模型,主线程作为生产者不断的向任务队列中添加任务,而线程池中的线程在不断从任务队列中拿任务。假设任务队列的容量是没有上限的。

和阻塞队列一样,要实现这么一个模型的关键依然是 放任务PushTask 和 取任务PopTask,除此之外,在创建线程的时候,有一个需要注意的细节
1、准备工作

2、创建线程
我们一次创建 4个线程,要传递给线程的参数暂定,为了方便,我们这里不主动回收线程,而是选择将线程分离。

这里需要注意的是,pthread_create函数的第三个参数,传入的函数必须满足
(1) 返回值是 void*
(2) 输入的参数只有一个,那就是void*

但是实际上,Routines是定义在类中的,是一个成员函数,参数会包含一个隐藏的this指针,所以站在编译器的角度就变成了 Routines(ThreadPool<T>* this , void* args),所以我们在函数的最开始加上 static
成员函数一般都是放在代码区,成员函数加了static以后,此时会被放到全局区,这个时候参数就只有void*,不会包含隐藏的this指针
3、PushTask函数
此时因为任务队列的容量没有上限,所以我们这里无需考虑任务队列为满的情况。_task_queue是临界资源,我们需要使用互斥锁来保护这个临界资源
互斥锁的初始化和销毁这里就不展示了。

还有一步我们需要等实现 PopTask函数以后再写

4、PopTask函数
取任务的时候,既要考虑到维护临界资源,又要考虑到任务队列为空的情况。
(1) 既然是维护临界资源,那就需要加锁和解锁
(2) 既然是考虑到任务队列是否为空,当任务队列为空的时候,说明消费者线程不能再继续取任务了,此时要把消费者线程加入到 条件变量中等待,当生产者线程加入任务时,再唤醒消费者线程。
条件变量的初始化和销毁,这里就不展示了。

PopTask函数具体实现如下:

PushTask函数的补充:

5、线程执行函数Routines
现在Routines被放到了全局区,但是线程池中的线程需要访问 任务队列,因此我们需要给线程执行函数传递 this指针,这样的话,每个线程就可以访问到类成员变量了

然后我们在线程执行函数中获得this指针,用一个名为that的指针来接收这个this指针

我们可以写一个空的Task类,就像下面这样

线程执行函数的完整代码如下:

三、模型测试
测试的主函数如下,主线程作为生产者线程每隔1s向任务队列添加任务。

这里表现出来的效果和之前的阻塞队列差不多

边栏推荐
- The technology boss is ready, and the topic of position C is up to you
- COM和CN
- ByteDance data Lake integration practice based on Hudi
- Introduce in detail how to communicate with Huawei cloud IOT through mqtt protocol
- [shutter] top navigation bar implementation (scaffold | defaulttabcontroller | tabbar | tab | tabbarview)
- 通达OA 首页门户工作台
- Where is the future of test engineers? Confused to see
- The testing process that software testers should know
- 我的创作纪念日
- Basic operation of view
猜你喜欢

Deep learning notes (constantly updating...)

How can retail enterprises open the second growth curve under the full link digital transformation

Depth (penetration) selector:: v-deep/deep/ and > > >

Flink CDC mongoDB 使用及Flink sql解析monggo中复杂嵌套JSON数据实现

stm32F407-------ADC

【Camera专题】OTP数据如何保存在自定义节点中

stm32F407-------DMA

Y54. Chapter III kubernetes from introduction to mastery -- ingress (27)

Servlet中数据传到JSP页面使用el表达式${}无法显示问题

通达OA v12流程中心
随机推荐
微信小程序开发工具 POST net::ERR_PROXY_CONNECTION_FAILED 代理问题
Prohibited package name
可视化yolov5格式数据集(labelme json文件)
502 (bad gateway) causes and Solutions
MySQL learning 03
Custom components, using NPM packages, global data sharing, subcontracting
String replace space
udp接收队列以及多次初始化的测试
返回一个树形结构数据
人脸识别6- face_recognition_py-基于OpenCV使用Haar级联与dlib库进行人脸检测及实时跟踪
[fluent] hero animation (hero animation use process | create hero animation core components | create source page | create destination page | page Jump)
苏世民:25条工作和生活原则
Leetcode(540)——有序数组中的单一元素
Analysis, use and extension of open source API gateway apisex
Kotlin middle process understanding and Practice (I)
单词单词单词
stm32F407-------ADC
Iptables layer 4 forwarding
微信小程序開發工具 POST net::ERR_PROXY_CONNECTION_FAILED 代理問題
Redis:Redis的简单使用