【Linux进程通信】使用匿名管道制作一个简单的进程池

进程池是什么呢?我们可以类比内存池的概念来理解进程池。

内存池

内存池是在真正使用内存之前,先申请分配一定数量的、大小相等(一般情况下)的内存块留作备用。当有新的内存需求时,就从内存池中分出一部分内存块,若内存块不够再继续申请新的内存。这样做的一个显著优点是,使得内存分配效率得到提升。

进程池

进程池是管理进程、资源进程组成的技术应用。进程池技术的应用至少由以下两部分组成:

管理进程:管理进程负责创建资源进程,把任务交给空闲的资源进程处理,回收已经处理完任务的资源进程。

资源进程:预先创建好的空闲进程,管理进程会把任务发送给空闲的资源进程处理。

管理进程要有效的管理资源进程,那么管理进程和资源进程之间必然需要交互,而他们就是通过管道进行信息交互的,还有其他的交互方式等等。

 制作一个简单的进程池的思路:我们为了实现两进程之间的通信(具有血缘关系的进程),父进程可以通过向子进程发送任务码来使子进程完成某个任务,传送信息的媒介就是匿名管道。

创建子进程并为每个子进程创建一个与父进程间进行通信的匿名管道。如下:

makefile 

ProcessPool:ProcessPool.ccg++ -o $@ $^ -std=c++11
.PHONY:clean
clean:rm -f ProcessPool

ProcessPool.hpp

#pragma once
#include <iostream>
#include <vector>
typedef void(*task)();//重命名函数指针类型
void task1()
{std::cout<<"更新野区"<<std::endl;
}
void task2()
{std::cout<<"回复生命值与法力值"<<std::endl;
}
void task3()
{std::cout<<"英雄升级"<<std::endl;
}
class Task
{public:task operator[](int pos){if(pos>=0 && pos<=3)return tasks[pos];}private:task tasks[4]={nullptr,task1,task2,task3};//函数指针数组
};

ProcessPool.cc

#include "Task.hpp"
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
#include <vector>
#include <cstdio>
#include <ctime>
#include <cassert>#define NUM 2
#define processnum 5class channel //创建描述管道写端和对应的子进程id的类
{public:channel(size_t cmdfd, pid_t slaverid, const std::string& slavername):_cmdfd(cmdfd)//用来确定父进程向那个管道发送任务码,_slaverid(slaverid)//子进程的pid,_slavername(slavername)//子进程的名字{}public:size_t _cmdfd;pid_t _slaverid;std::string _slavername;
};void Reader()
{Task t;while(true){int childtaskcode;int n = read(0, &childtaskcode, sizeof(childtaskcode));if(0==n)//如果0==n则说明父进程的写端已关闭或父进程已终止break;else if(n==sizeof(int))t[childtaskcode]();}
}
void InitProcessPool(std::vector<channel>& channels)
{std::vector<int> uselesswfd;for(int i=0;i<processnum;i++){int pipefd[NUM]={0};int n = pipe(pipefd);assert(!n);pid_t id = fork();//childif(0 == id){std::cout<<"child process delete uselesswfd:";for(auto e:uselesswfd){close(e);std::cout<< e <<" ";}std::cout<<std::endl;close(pipefd[1]);dup2(pipefd[0], 0);Reader();std::cout<<"child exit pid is:"<<getpid()<<std::endl;exit(0);}//parentuselesswfd.push_back(pipefd[1]);close(pipefd[0]);std::string name="process" + std::to_string(i);channels.push_back(channel(pipefd[1], id, name));//记录每一个管道的写端以及对应子进程pid}
}void Menu()
{std::cout<<"******************************************"<<std::endl;std::cout<<"*******1.更新野区  2.回复生命值与法力值*****"<<std::endl;std::cout<<"*******3.英雄升级  0.退出             *****"<<std::endl;
}
void ControlChildProcess(const std::vector<channel>& channels) 
{int whichprocess=0;srand(time(nullptr));while(true){sleep(1);std::cout<<std::endl;Menu();int taskcode;std::cout<<"Please select taskcode:";std::cin>>taskcode;if(taskcode<0 || taskcode>3){std::cout<<"找不见对应的任务码!"<<std::endl;continue;}if(0==taskcode)break;whichprocess = rand()%channels.size();write(channels[whichprocess]._cmdfd, &taskcode, sizeof(taskcode));}
}void Quitwaitchild(const std::vector<channel>& channels)
{for(auto& e : channels)close(e._cmdfd);for(auto& e : channels)waitpid(e._slaverid, nullptr,0);
}int main()
{//描述并组织管道写端fd以及子进程pidstd::vector<channel> channels;//用于存储管道和其对应的子进程信息//创建进程池,子进程阻塞等待管道内容InitProcessPool(channels);//父进程控制子进程,向子进程发送任务码让子进程执行相应的任务,并间接控制子进程终止ControlChildProcess(channels);//终止子进程并且父进程等待回收子进程Quitwaitchild(channels);return 0;
}

程序演示如下:

 

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

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

相关文章

web权限到系统权限 内网学习第一天 权限提升 使用手工还是cs???msf可以不??

现在开始学习内网的相关的知识了&#xff0c;我们在拿下web权限过后&#xff0c;我们要看自己拿下的是什么权限&#xff0c;可能是普通的用户权限&#xff0c;这个连添加用户都不可以&#xff0c;这个时候我们就要进行权限提升操作了。 权限提升这点与我们后门进行内网渗透是乘…

C#编程命名笔记

1.变量名的命名规则->要求用“匈牙利法则” 变量类型特征位数命名规则例子bool 用b开头bUpdatesbyte有符号8位用sby开头sbyTypebyte无符号8位用by开头byTypeshort有符号16位用n开头nStepCountushort无符号16位用un开头unCountint有符号32位用i开头iCountuint&#xff08;WO…

MySQL:设计数据库与操作

设计数据库 1. 数据建模1.1 概念模型1.2 逻辑模型1.3 实体模型主键外键外键约束 2. 标准化2.1 第一范式2.2 链接表2.3 第二范式2.4 第三范式 3. 数据库模型修改3.1 模型的正向工程3.2 同步数据库模型3.3 模型的逆向工程3.4 实际应用建议 4. 数据库实体模型4.1 创建和删除数据库…

Linux 磁盘空间清理

1.检查磁盘使用情况 #显示每个挂载点的磁盘使用量&#xff0c;以及可用空间和使用率 df -h #显示当前目录的全部文件和目录&#xff08;包括隐藏的&#xff09;,以MB显示 ll -h 2. du查看最大的目录或文件 #逐级检查某个目录下各个子目录的大小。从根目录开始&#xff0c;逐级…

Linux_应用篇(25) SPI 应用编程基础

SPI基础知识 SPI&#xff08;Serial Peripheral Interface&#xff0c;串行外设接口&#xff09;是一种同步串行通信协议&#xff0c;广泛应用于微控制器和各种外围设备之间的数据传输。它由摩托罗拉公司在20世纪80年代开发&#xff0c;具有高速、全双工通信的特点&#xff0c…

基于x86+FPGA+AI轴承缺陷视觉检测系统,摇枕弹簧智能检测系统

一、承缺陷视觉检测系统 应用场景 轴类零件自动检测设备&#xff0c;集光、机、软件、硬件&#xff0c;智能图像处理等先进技术于一体&#xff0c;利用轮廓特征匹配&#xff0c;目标与定位&#xff0c;区域选取&#xff0c;边缘提取&#xff0c;模糊运算等算法实现人工智能高…

PCL 点云聚类(基于体素连通性)

文章目录 一、简介二、实现代码三、实现效果参考资料一、简介 这里的思路很简单,我们通过将点云转换为体素,基于体素的连通性实现对点云的聚类(有点类似于欧式聚类),不过这种方式进行的聚类有些粗糙,但聚类速度相对会快很多,具体的实现效果可以详细阅读代码。 二、实现代…

[AIGC] Java HashMap原理解析:深入探索键值对存储和检索的内部机制

HashMap是Java中最常用的数据结构之一&#xff0c;它提供了高效的键值对存储和检索能力。本文将深入探索Java HashMap的内部机制&#xff0c;详细介绍其原理和工作流程。 文章目录 一、HashMap的数据结构二、哈希冲突处理三、哈希算法四、键值对的存储和检索五、扩容和负载因子…

提高候选人的招聘感受:成功的策略

大约78%的候选人表示&#xff0c;他们的整体应聘体验表明企业对员工的关注。然而&#xff0c;超过一半的候选人透露&#xff0c;他们在招聘过程中有过负面的候选人经历&#xff0c;80%的候选人在经历了令人失望的招聘过程后会公开与他人分享他们的不良经历。 但也有一线希望&am…

Perl的上下文之谜:深入理解上下文概念

&#x1f577;️ Perl的上下文之谜&#xff1a;深入理解上下文概念 Perl&#xff0c;这门被誉为“只需一条命令就能完成任务”的编程语言&#xff0c;以其强大的文本处理能力而闻名。在Perl中&#xff0c;上下文是一个核心概念&#xff0c;它决定了变量的解释方式以及操作符的…

在nginx中设置相对路径跳转的方式

在nginx中的location中&#xff0c;设置301或302的跳转的方式一般是这样的 # 302跳转 location ~ ^/old/$ {return 302 /new/; }# 301跳转 location ~ ^/old/$ {return 301 /new/; }这里/new/虽然写的是相对路径&#xff0c;但是nginx依然会补齐url的前缀&#xff0c;这样在…

某某市信息科技学业水平测试软件打开加载失败逆向分析(笔记)

引言&#xff1a;笔者在工作过程中&#xff0c;用户上报某某市信息科技学业水平测试软件在云电脑上打开初始化的情况下出现了加载和绑定机器失败的问题。一般情况下&#xff0c;在实体机上用户进行登录后&#xff0c;用户的账号信息跟主机的机器码进行绑定然后保存到配置文件&a…

Echarts-散点图

1.案例1 1.1代码 option = {xAxis: {scale: true,splitLine: {show: false},axisLabel: {show: true,textStyle: {color: white, //更改坐标轴文字颜色}}},yAxis: {show:false,scale: true,splitLine: {show: true,lineStyle: {type: dashed,}},axisLabel: {show: true ,tex…

毛概客观题题库

第一章毛泽东思想及其历史地位 一、单选题 2.1917年&#xff08; &#xff09;的胜利开辟了世界无产阶级社会主义革命的新时代&#xff0c;也给中国送来了马克思列宁主义.... A.俄国十月革命 B.五四运动 C.中国共产党建立 D.中华人民共和国建立 4.标志着毛泽东思想开始萌…

第十四届蓝桥杯省赛C++B组E题【接龙数列】题解(AC)

需求分析 题目要求最少删掉多少个数后&#xff0c;使得数列变为接龙数列。 相当于题目要求求出数组中的最长接龙子序列。 题目分析 对于一个数能不能放到接龙数列中&#xff0c;只关系到这个数的第一位和最后一位&#xff0c;所以我们可以先对数组进行预处理&#xff0c;将…

C++初学者指南-3.自定义类型(第一部分)-析构函数

C初学者指南-3.自定义类型(第一部分)-析构函数 文章目录 C初学者指南-3.自定义类型(第一部分)-析构函数特殊的成员函数用户定义的构造函数和析构函数RAII示例&#xff1a;资源处理示例&#xff1a;RAII记录零规则 特殊的成员函数 T::T()默认构造函数当创建新的 T 对象时运行。…

电脑录音方法:电脑怎么录音?5招轻松搞定录音!

想要从麦克风或系统音频录制电脑声音吗&#xff1f;这是一项简单的任务。本文将为您介绍5种最佳且最简单的方法&#xff0c;包括使用Windows系统自带的录音工具来录制电脑音频&#xff0c;在线音频录音软件和专业的第三方电脑录音软件。这些工具都能够很好地帮助您完成电脑怎么…

在树莓派上安装中文输入法

在树莓派上安装中文输入法&#xff0c;可以使用 fcitx 输入法框架&#xff0c;它支持多种中文输入法&#xff0c;如拼音、五笔等。以下是详细步骤&#xff1a; 1. 更新系统 首先&#xff0c;确保你的系统是最新的&#xff1a; sudo apt update sudo apt upgrade2. 安装 fcit…

江苏高防IP对网络安全有何作用?

网络科技在快速发展的过程中&#xff0c;网络安全问题也日益增加&#xff0c;许多网站行业和服务器会受到DDOS攻击和CC攻击等多种恶意的网络攻击&#xff0c;这些攻击给企业带来了巨大的经济损失&#xff0c;同时也导致服务器出现瘫痪和网站无法正常运行的情况&#xff0c;为了…

一款十六进制编辑器,你的瑞士军刀!!【送源码】

软件介绍 ImHex是一款功能强大的十六进制编辑器&#xff0c;专为逆向工程师、程序员以及夜间工作的用户设计。它不仅提供了基础的二进制数据编辑功能&#xff0c;还集成了一系列高级特性&#xff0c;使其成为分析和修改二进制文件的理想工具。 功能特点 专为逆向工程、编程和夜…