【Linux】匿名管道的应用场景 --- 进程池

在这里插入图片描述

👦个人主页:Weraphael
✍🏻作者简介:目前正在学习c++和算法
✈️专栏:Linux
🐋 希望大家多多支持,咱一起进步!😁
如果文章有啥瑕疵,希望大佬指点一二
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注😍


前言

本篇博客不会对代码有非常详细的解析,但是只要你看完这篇博客(点击跳转),然后再来看这篇,我保证跟看小说一样 ~

目录

  • 前言
  • 一、池化技术
  • 二、设计思路
  • 三、代码实现之管理管道
  • 四、代码实现之创建子进程和初始化管道字段
  • 五、代码实现之任务列表
  • 六、代码实现之发布任务
  • 七、代码实现之读取任务
  • 八、代码实现之菜单版
  • 九、代码实现之子进程回收
  • 十、一个隐藏bug
  • 十一、相关代码

一、池化技术

不知道大家有没有听过xx池(如内存池等),这些池其实统称池化技术

以内存池为例,比方说有一个偏远的村庄,这个村庄离河边有一定距离,那么村民需要水的时候就跑去河边打水,可是每次需要水的时候就去打未免效率太低了。因此,村民可以提前打完一周所需要的用水。

因此,可以将村民看作是程序,而水则是内存。在没有内存池的情况下,程序每次需要内存时都需要向操作系统申请,而频繁进行系统调用是有成本的,就像村民每次需要水都要跑去河边打水一样,效率较低。而有了内存池,就像村民提前打好一周的水存放在家里一样,程序在启动时就预先分配了一定量的内存,并将其存放在内存池中。当程序需要内存时,就直接从内存池中获取,而不是每次都向系统请求,这样可以减少内存分配的开销和系统的负担,提高程序的运行效率。

因此,不管是xx池,这些池化技术的共同特点是:通过提前分配一定数量的资源并在需要时复用这些资源,来提高系统的性能和效率。

进程池是一种并发编程中常用的技术,特别是在需要处理大量任务的情况下。它类似于内存池的概念,想象一下有很多任务需要处理,而每个任务都需要独立的进程来执行。如果每次都创建一个新的进程来处理任务(如创建进程控制块、进程地址空间等),会增加系统开销和资源消耗,特别是在任务量大的情况下。这时,就可以使用进程池。

进程池在程序启动时就会创建一定数量的进程,并将它们保存在池中。当有任务需要执行时,就从池中获取一个空闲的进程来处理任务,任务执行完毕后,该进程不会被销毁,而是返回到池中,等待下一个任务的到来。这样可以避免频繁创建和销毁进程的开销,提高系统的性能和效率。

二、设计思路

请添加图片描述

首先我们可以通过父进程bash,来提前创建好若干个子进程。接下来为了让父进程和这些子进程建立联系,在父进程和子进程之间设计匿名管道,父进程下达任务数据到管道中,再由子进程接收任务并执行。

三、代码实现之管理管道

为了让子进程和父进程建立可靠的数据传输通道,应该要对管道进行管理。那么就要先描述,再组织。

描述管道的字段有:

  • _cmdfd:父进程需要向哪个管道发送任务,因此需要知道各管道的写端,即文件描述符。
  • _sonid:当父进程将任务发送到管道中时,子进程可以通过自己的pid来确定是否是自己需要执行的任务。

在这里插入图片描述

四、代码实现之创建子进程和初始化管道字段

我们可以封装一个函数创建子进程,并且初始化子进程对应的管道字段。具体代码如下:

在这里插入图片描述

传参的小技巧

  1. 输入型参数:用于传递数据给函数,但形参的改变不用影响实参 -> const&
  2. 输出型参数:形参改变要影响实参,当函数被调用时,输出型参数可以不初始化 -> *
  3. 输入输出型参数:和输出型参数的区别是 -> 这些参数在函数调用前需要被初始化 -> &

我们可以通过打印的方式来来验证是否真的创建成功了

在这里插入图片描述

【程序结果】

在这里插入图片描述

五、代码实现之任务列表

新建一个文件名为tasks.hpp,里面用来存放任务的实现。具体代码如下:

补充:.hppc++常见的头文件。该文件中通常会包含类的定义、模板类和函数的实现,即定义和声明不分离。

在这里插入图片描述

六、代码实现之发布任务

父进程需要发布任务给进程池中的任意一个进程,需要经历以下步骤:

  1. 选择任务。这里我们可以这样规定:我使用一个数据结构(如vector)管理任务列表,然后父进程可以通过随机选取任务列表中的下标,我们可以称为任务码。最后将这个任务码发送给子进程,让子进程来执行任务码对应的任务。
  2. 选择进程:我们可以随机选取进程池中的任意一个进程来执行。
  3. 发布任务:将任务码写入到管道文件中

首先我们需要将任务列表中的所有任务用一种数据结构管理起来,这里就以vector为例

C++标准库中的 <functional> 头文件提供了一组模板类和函数,用于实现函数对象(包括函数指针)的封装、组合和操作

在这里插入图片描述

接下来我们需要控制任意一个进程来执行任务

在这里插入图片描述

七、代码实现之读取任务

在这里插入图片描述

【程序结果】

在这里插入图片描述

八、代码实现之菜单版

我们只需要修改【发布任务】的代码即可实现

在这里插入图片描述

【程序结果】

在这里插入图片描述

九、代码实现之子进程回收

如上菜单所示,当程序退出的时候,可以选择将子进程回收

在这里插入图片描述

【程序结果】

在这里插入图片描述

十、一个隐藏bug

在这里插入图片描述

当我们的父进程创建子进程的时候,因为我们用的是循环的方式,所以导致父进程每创建一个子进程,那么下一个进程就会继承上一个管道的写端。这样子进程之间也可以相互进行通信了。

那有什么问题呢?我们上面代码都跑的好好的呀!但如果你写出以下代码,就是一个bug

在这里插入图片描述

【程序结果】

在这里插入图片描述

为什么会阻塞呢?

在关闭第一个进程的时候,我们先是将写端关闭,那么对应的读端的read函数就会返回0,表示可以退出通信了。退出通信后代码就要开始回收第一个进程。可是,第二个进程甚至后面的进程都继承了这个写端(写端没关完),那么操作系统还是认定系统还在通信,那么read函数就不会返回0,可是我们在关闭文件描述符后,紧接就要回收这第一个进程了,可是第一个进程还在通信,并没有退出,那么系统就要等待它退出,所以就阻塞了。

  • 解决方法1:先将文件描述符全部关闭,再回收所有子进程。(最开始的方案)

  • 解决方法2:可以关闭和回收一起做。只需要倒着来就行。(可以配合刚开始的那个图理解)

在这里插入图片描述

【运行结果】

在这里插入图片描述

  • 解决方法3:让一个管道只有一个读端,一个写端。在创建一个子进程前,将继承父进程的写端文件描述符关闭即可。

在这里插入图片描述

【程序结果】

在这里插入图片描述

十一、相关代码

Gitee仓库链接:点击跳转

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/25403.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt qtpropertybrowser使用实例(1)

属性界面实例&#xff1a; 代码如下&#xff1a; #include <QDate> #include <QLocale> #include "qtpropertymanager.h" #include "qtvariantproperty.h" #include "qttreepropertybrowser.h" int main(int argc, char *argv[]) {…

nginx mirror流量镜像详细介绍以及实战示例

nginx mirror流量镜像详细介绍以及实战示例 1.nginx mirror作用2.nginx安装3.修改配置3.1.nginx.conf3.2.conf.d目录下添加default.conf配置文件3.3.nginx配置注意事项3.3.nginx重启 4.测试 1.nginx mirror作用 为了便于排查问题&#xff0c;可能希望线上的请求能够同步到测试…

TalkingData 是一家专注于提供数据统计和分析解决方案的独立第三方数据智能服务平台

TalkingData 是一家专注于提供数据统计和分析解决方案的独立第三方数据智能服务平台。通过搜索结果&#xff0c;我们可以了解到 TalkingData 的一些关键特性和市场情况&#xff0c;并将其与同类型产品进行比较。 TalkingData 产品特性 数据统计与分析&#xff1a;提供专业的数…

【每日算法】

算法第15天| (二叉树part02)层序遍历、226.翻转二叉树(优先掌握递归)、101. 对称二叉树(优先掌握递归) 文章目录 算法第15天| (二叉树part02)层序遍历、226.翻转二叉树(优先掌握递归)、101. 对称二叉树(优先掌握递归)一、层序遍历二、226. 翻转二叉树(优先掌握递归)三、101. 对…

Elasticsearch index 设置 false,为什么还可以被检索到?

在 Elasticsearch 中&#xff0c;mapping 定义了索引中的字段类型及其处理方式。 近期有球友提问&#xff0c;为什么设置了 index: false 的字段仍能被检索。 本文将详细探讨这个问题&#xff0c;并引入列式存储的概念&#xff0c;帮助大家更好地理解 Elasticsearch 的存储和查…

基于STM32F030设计的多点温度采集系统(BC26+OneNet)

一、项目背景 随着物联网技术的迅猛发展&#xff0c;越来越多的智能设备应运而生&#xff0c;而温度采集系统是其中重要的一类。在现代工业和家庭生活中&#xff0c;温度对于生产、居住和储存等过程的控制有着非常重要的作用。因此&#xff0c;准确地采集环境温度数据并进行处…

HTML做成一个粒子漩涡特效页面

大家好&#xff0c;今天制作制作一个粒子漩涡特效的页面&#xff01; 先看具体效果&#xff1a; 要在一个单一的 index.html 页面中实现粒子漩涡特效&#xff0c;我们可以使用HTML、CSS和JavaScript&#xff08;不需要外部库&#xff09;。下面是一个简单的例子&#xff0c;展…

JWT 从入门到精通

什么是 JWT JSON Web Token&#xff08;JWT&#xff09;是目前最流行的跨域身份验证解决方案 JSON Web Token Introduction - jwt.ioLearn about JSON Web Tokens, what are they, how they work, when and why you should use them.https://jwt.io/introduction 一、常见会…

Git发布正式

一般我们开发都是在测试环境开发&#xff0c;开发完成后再发布到正式环境。 一.分支代码合并到主分支1.首先切换到自己的分支(比如分支叫&#xff1a;dev)git checkout dev2.把本地分支拉取下来git pull 或者 git pull origin dev3.切换到主分支mastergit checkout master4.更新…

【Vue】购物车案例-构建项目

脚手架新建项目 (注意&#xff1a;勾选vuex) 版本说明&#xff1a; vue2 vue-router3 vuex3 vue3 vue-router4 vuex4/pinia vue create vue-cart-demo需要勾选上vuex&#xff0c;由于这个项目只有一个页面&#xff0c;vuex可勾可不勾 将原本src内容清空&#xff0c;替换成教学…

【计算机网络基础】IP地址

文章目录 一、IP介绍IP地址和Mac地址IP地址分类 二、IPV4地址IPV4地址分类子网掩码进制转换方法8421法则转换法私网地址PNAT技术IP分配原则 三、IPv6地址IPV6组成IPV6分类IPV6特殊地址 四、VLSM可变长子网掩码划分子网VLSM优点 &#x1f308;你好呀&#xff01;我是 山顶风景独…

springboot+mqtt使用总结

1.软件的选型 1.1.使用免费版EMQX 1.1.1.下载 百度搜索的目前是会打开官网&#xff0c;这里提供下免费版的使用链接EMQX使用手册 文档很详细&#xff0c;这里不再记录了。 1.2.使用rabbitmq rabbitmq一般做消息队列用&#xff0c;作为mqtt用我没有找到详细资料&#xff0c…

2013年 阿拉斯加巴罗活动层厚度和土壤含水量

Pre-ABoVE: Active Layer Thickness and Soil Water Content, Barrow, Alaska, 2013 ABoVE前&#xff1a;阿拉斯加巴罗活动层厚度和土壤含水量&#xff0c;2013年 简介 文件修订日期&#xff1a;2018-01-10 数据集版本&#xff1a;1 摘要 该数据集提供了 2013 年 8 月在…

Java | Leetcode Java题解之第142题环形链表II

题目&#xff1a; 题解&#xff1a; public class Solution {public ListNode detectCycle(ListNode head) {if (head null) {return null;}ListNode slow head, fast head;while (fast ! null) {slow slow.next;if (fast.next ! null) {fast fast.next.next;} else {ret…

网络安全难学吗?2024该怎么系统学习网络安全?

学习网络安全需要循序渐进&#xff0c;由浅入深。很多人对网络安全进行了解以后&#xff0c;就打算开始学习网络安全&#xff0c;但是又不知道怎么去系统的学习。 网络安全本身的知识不难&#xff0c;但需要学习的内容有很多&#xff0c;其中包括Linux、数据库、渗透测试、等保…

linux-ubuntu20网卡驱动安装AX201

https://blog.csdn.net/vor234/article/details/131682778 联想拯救者Y7000P2023 Ubuntu20.04网卡驱动AX211安装 幻14 ubuntu20.04 AX210驱动安装 官网下载相应的驱动&#xff1a;https://www.intel.com/content/www/us/en/support/articles/000005511/wireless.html sudo a…

AI生成个性化壁纸

使用天工AI 将图片设置成桌面壁纸

vivado HW_ILA

HW_ILA 描述 集成逻辑分析器&#xff08;ILA&#xff09;调试核心允许您执行系统内监控 通过对内核上的调试探针&#xff0c;在实现的设计中对信号进行处理。您可以配置 ILA核心实时触发特定硬件事件&#xff0c;并在 以系统速度探测。 ILA调试核心可以通过从IP目录实例化ILA核…

【微信小程序】事件分类以及阻止事件冒泡

在微信小程序中&#xff0c;事件分为冒泡事件和非冒泡事件两大类&#xff0c;它们的区别在于事件是否能从原始触发组件开始&#xff0c;向父级组件传播&#xff08;即“冒泡”&#xff09;。 冒泡事件&#xff1a;当一个组件上的事件被触发后&#xff0c;不仅当前组件会接收到这…