Linux操作系统小项目——实现《进程池》

文章目录

  • 前言:
  • 代码实现:
  • 原理讲解:
    • 细节处理:

前言:

在前面的学习中,我们简单的了解了下进程之间的通信方式,目前我们只能知道父子进程的通信是通过匿名管道的方式进行通信的,这是因为这点我们就可以简简单单的来写一个项目————进程池

代码实现:

Task.hpp文件

#include <iostream>
#include <string>
#include <vector>
#include <unistd.h>
#include <cstdlib>
#include <sys/types.h>
#include <sys/wait.h>class Channel
{
public:Channel(int wfd, int child_process_id, std::string child_process_name): _wfd(wfd), _child_process_id(child_process_id), _child_process_name(child_process_name){}~Channel(){}int Get_wfd() { return _wfd;}int Get_child_process_id() { return _child_process_id;}std::string Get_child_process_name() { return _child_process_name;}void CloseChannel() { close(_wfd); }void Wait(){pid_t rid = waitpid(_child_process_id, nullptr, 0);if (rid < 0){std::cerr << "Filed to wait" << std::endl;exit(1);}std::cout << "Wait success!" << std::endl;}private:int _wfd;int _child_process_id;std::string _child_process_name;
};void task_print()
{std::cout << "Hey! This is task_print" << std::endl;
}void task_load()
{std::cout << "Yo! This is task_load" << std::endl;
}void task_flush()
{std::cout << "Dude! This is task_flush" << std::endl;
}typedef void (*task_ptr)(void); // function pointertask_ptr task_arr[3]; // function pointer's arrayvoid TaskLoad()
{srand((unsigned int)time(NULL));task_arr[0] = task_print;task_arr[1] = task_load;task_arr[2] = task_flush;std::cout << "Task are all be loaded!" << std::endl;std::cout << "------------------------" << std::endl;
}int ChoseTask()
{int n = rand() % 3;return n;
}int PipeNumber(int times)
{static int _pipe = 0;int next = _pipe;_pipe++;_pipe %= times;return next;
}void WriteToPipe(int p_number, int t_number, std::vector<Channel> Channels)
{static int i = 1;int n = write(Channels[p_number].Get_wfd(), &t_number, sizeof(t_number));if(n < 0) {std::cerr << "failed to write" << std::endl;exit(1);}std::cout << i++ << "->the number of task '" << t_number << "' have writen in pipe ' " << p_number << "' already" << std::endl;
}void work(int rfd)
{while(true){sleep(1);int file_buffer = 0;int n = read(rfd, &file_buffer, sizeof(file_buffer));if(n < 0){std::cerr << "Failed to read" << std::endl;exit(1);}else if(n == 0){std::cout << "child process : " << getpid() << " quit" << std::endl;break;}task_arr[file_buffer]();}
}

processpool.cc文件

#include "Task.hpp"void CreateChannels(int nums, std::vector<Channel> *Channels)
{for (int i = 0; i < nums; ++i){// create pipeint pipefd[2] = {0};int n = pipe(pipefd);if (n < 0){std::cerr << "Failed to create pipe" << std::endl;exit(1);}// create child processint pid = fork();if (pid == 0){// childif (!Channels->empty()){std::cout << "----Before I close my pipefd[1], I have to close the wfd which inherited by the father process's struct files_struct!" << std::endl;for (auto &channel : *Channels)channel.CloseChannel();}std::cout << "Here is child process!" << std::endl;close(pipefd[1]); // as child process close unnecessary wfdwork(pipefd[0]);close(pipefd[0]);exit(0);}// fatherstd::string name = "Channel No.";std::string Number = std::to_string(i);name += i;close(pipefd[0]); // as father process close unnecessary rfdChannels->push_back({pipefd[1], pid, name});}
}void ControlChannels(int times, std::vector<Channel> Channels)
{for (int i = 0; i < times; ++i){sleep(1);// chose pipe number to be writen in pipeint pipe_number = PipeNumber(times);// chose task number to write in pipeint task_number = ChoseTask();// write task number to the pointed pipeWriteToPipe(pipe_number, task_number, Channels);}
}void CleanChannels(std::vector<Channel> Channels)
{for (auto &channel : Channels){channel.CloseChannel();// channel.Wait();}// for (auto &channel : Channels)// {//     channel.Wait();// }
}int main(int argc, char *argv[])
{if (argc == 1){std::cerr << "Need more argc! need more option!" << std::endl;return 1;}int nums = std::stoi(argv[1]);std::vector<Channel> Channels;// load all the functionTaskLoad();// 1、create channels and child processCreateChannels(nums, &Channels);// 2、control channelsControlChannels(nums, Channels);// 3、free channels and wait child process exitCleanChannels(Channels);// sleep(100);return 0;
}

原理讲解:

其实这个进程池项目通过画图就很好能做出来:
image-20241010102548398

细节处理:

  1. 由图片可知,未来可能我们要实现很多个任务的时候完全可以采用进程池的方式来解决,与之前处理任务不同的是,以前我们是要执行一个任务就创建一个子进程,而这个不一样,现在是提前就已经开辟好了一堆子进程。
    所以先提前创建好适量的子进程,有任务就交给子进程执行,这么做更适合多任务的并发操作,因为节省了创建子进程的操作。

  2. 未来master可以将任务发送至管道内部,以此来唤醒子进程来处理任务,但是要注意父进程不可针对的使用同一个管道,应当在多个管道直接轮询写入,这就保证了后端任务划分的负载均衡

  3. 具体的实现将任务发送至管道内部,从代码的角度来看其实就是将函数发送到管道之中,所以我们可以先创建一个函数指针数组来进行管理各个函数,未来在将任务写入至管道也仅仅需要传递下标(数字)即可。

  4. 在回收的时候我们也要额外注意!我们可以先让父进程遍历所有管道并关闭所有管道的wfd(这主要依据管道的5种特征——“若是管道的wfd关闭了,且rfd还没关闭,那么迟早会读到文件末尾,那么read系统调用就会返回0,就会结束读取”),再遍历一遍,等待每一个子进程退出。等待的原因其实是为了能够在子进程执行完后进行回收,从而避免出现“孤儿进程”。

  5. (BUG!!!!!)切记!不可以一边关闭管道的wfd再等待子进程退出,这会造成子进程阻塞!!!
    image-20241010104818857

    image-20241010105101099

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

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

相关文章

JAVA自动化测试TestNG框架

1.TestNG简介 JAVA自动化测试最重要的基石。官网&#xff1a;https://testng.org 使用注解来管理我们的测试用例。 发现测试用例 执行测试用例 判断测试用例 生成测试报告 2.创建Maven工程 2.1创建一个maven工程 2.2设置maven信息 2.3设置JDK信息 2.4引入testng依赖 <dep…

软考高级系统规划与管理师,都是精华知识点!

知识点&#xff1a;信息的定义和属性 1、 信息的基本概念 l 信息是客观事物状态和运动特征的一种普遍形式&#xff0c;客观世界中大量地存在、产生和传递着以这些方式表示出来的各种各样的信息。 l 维纳&#xff08;控制论创始人&#xff09;&#xff1a;信息就是信息&#…

指针——数据结构解惑

文章目录 一.取指针和解指针二.为什么用指针&#xff1f; 指针存的是地址 一.取指针和解指针 int main() {int a0;int * p ;//声明int类型的**指针**char * m ;//声明char类型的**指针**&a;//a是个变量&#xff0c;&a&#xff0c;把地址取出来p&a;//p指针存的a的地…

双十一性价比高的宠物空气净化器推荐,希喂、美的、352测评分享

不知不觉这一年就要过去了&#xff0c;别问我为什么这么感伤&#xff0c;因为双十一要来了&#xff0c;我要开始”剁手“了&#xff0c;尤其是必须得买宠物空气净化器。 因为我家里养了两只猫&#xff0c;超级爱掉毛&#xff0c;每天为了清理这些猫毛我都要烦死了&#xff0c;…

LangChain4j使用阿里云百炼 进行AI调用

LangChain4j 介绍 LangChain4j 是一个专为Java开发者设计的开源库&#xff0c;旨在简化将大型语言模型&#xff08;LLM&#xff09;集成到Java应用程序中的过程。它于2023年初开发&#xff0c;灵感来源于Python和JavaScript的LLM库&#xff0c;特别是为了填补Java领域在这一方面…

支持阅后即焚的笔记Enclosed

什么是 Enclosed &#xff1f; Enclosed 是一个简约的网络应用程序&#xff0c;旨在发送私人和安全的笔记。所有笔记均经过端到端加密&#xff0c;确保服务器和存储对内容一无所知。用户可以设置密码、定义有效期 (TTL)&#xff0c;并选择在阅读后让笔记自毁。 软件特点&#x…

软考高项一年只考一次,2025 年会更难考吗?

根据近几年的考试情况来看&#xff0c;可以推测25年的高项考试可能会更加困难。值得关注的是2024年的考试情况&#xff0c;当年的高项考试是第二次机考&#xff0c;考试形式已经相对稳定。上午考试的科目知识点分布保持稳定&#xff0c;包括1道综合计算题和2道分析题的案例分析…

决策树和集成学习的概念以及部分推导

一、决策树 1、概述 决策树是一种树形结构&#xff0c;树中每个内部节点表示一个特征上的判断&#xff0c;每个分支代表一个判断结果的输出&#xff0c;每个叶子节点代表一种分类结果 决策树的建立过程&#xff1a; 特征选择&#xff1a;选择有较强分类能力的特征决策树生成…

【工欲善其事】巧用 PowerShell 自动清除复制 PDF 文本时夹杂的换行符号

文章目录 巧用 PowerShell 自动清除复制 PDF 文本时夹杂的换行符号1 问题描述2 解决方案3 具体步骤4 效果测试5 小结与复盘 巧用 PowerShell 自动清除复制 PDF 文本时夹杂的换行符号 1 问题描述 不知各位是否也为复制过来的文本中夹杂的回车换行符抓狂过&#xff1f;就是在复…

python 爬虫 入门 一、基础工具

目录 一&#xff0c;网页开发者工具的使用 二、通过python发送请求 &#xff08;一&#xff09;、get &#xff08;二&#xff09;、带参数的get &#xff08;三&#xff09;、post 后续&#xff1a;数据解析 一&#xff0c;网页开发者工具的使用 我们可以用 requests 库…

国际期货收费行情源CTP推送式/期货配资软件开发对接行情源的技术性说明

在现代金融市场中&#xff0c;期货交易因其高风险和高回报特性而备受关注。为了满足期货交易者的需求&#xff0c;开发高效、稳定和安全的期货交易软件变得尤为重要。本文将对国际期货收费行情源CTP推送式及期货配资软件的开发对接行情源的技术细节进行详细说明。 一、CTP&…

2024双十一值得购买的好物有哪些?看完这五款好物让你不后悔!

随着一年一度的双十一购物狂欢节即将拉开帷幕&#xff0c;作为一名热衷于分享购物心得的博主&#xff0c;我今天特别想在这里为大家详细介绍五款我个人非常期待入手的好物。这些产品都是经过我精心挑选和试用的&#xff0c;我相信它们不仅能够满足我的需求&#xff0c;同样也能…

visio导出pdf公式变形问题杂谈

其实不会变形。 我自己的情况是直接用edge PDF阅读器打开pdf看到的是公式有变形&#xff08;常见是字体、形状变了&#xff09;&#xff0c;但换一个pdf阅读器如adobe的就是正常的了 不过大家一般是用edge pdf阅读器直接打开查看&#xff0c;所以通过visio打印的方式导出pdf可…

力扣46~50题

题46&#xff08;中等&#xff09;&#xff1a; 分析&#xff1a; 见注释 python代码&#xff1a; class Solution:def permute(self, nums: List[int]) -> List[List[int]]:#长度小于6&#xff0c;不就是告诉我用递归嘛res[]#递归函数def call_back(p_list,n_list):#判断…

Cesiumlab发布3dtiles白膜流程与前端可视化加载

Cesiumlab发布3dtiles白膜流程与前端可视化加载 1.前置准备 1.1 安装CesiumLab并注册(CesiumLab安装、CesiumLab账号注册以及不同授权类型的说明 CesiumLab系列教程 - 知乎 (zhihu.com))&#xff1b; 1.2 最好安装有Qgis可以进行简单数据处理&#xff08;如果有完整数据可以…

可以在桌面上用的倒计时提醒app下载

在忙碌的工作日常中&#xff0c;我们常常需要记住各种截止日期和重要事件。为了确保这些任务按时完成&#xff0c;一款桌面倒计时提醒应用变得尤为重要。想象一下&#xff0c;当你在电脑桌面上就能清晰地看到剩余时间&#xff0c;这无疑会增加你的工作效率和紧迫感。 敬业签就…

华为eNSP实验:交换机流量控制之流量抑制

一、交换机流量控制之流量抑制 流量抑制是一种网络管理技术&#xff0c;用于防止过量的数据流通过网络设备&#xff0c;从而避免网络拥塞和性能下降。具体如下&#xff1a; 基本原理&#xff1a; 流量抑制通过设置特定的阈值来限制网络中的数据流量。当某个端口或接口的入站流…

Vue是一套构建用户界面的渐进式框架,常用于构建单页面应用

学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……&#xff09; 2、学会Oracle数据库入门到入土用法(创作中……&#xff09; 3、手把手教你开发炫酷的vbs脚本制作(完善中……&#xff09; 4、牛逼哄哄的 IDEA编程利器技巧(编写中……&#xff09; 5、面经吐血整理的 面试技…

u盘制作启动盘 重装windows系统

操作步骤一般都是把镜像iso文件下载好,然后使用u盘作为启动盘,使用启动盘制作工具,制作 官方重装系统程序 windows10系统下载连接 下载后点击启动 1 就是傻瓜式的安装 u盘安装就选2 然后一路下一步即可 等待完成,启动盘就制作好了 使用rufus 选择对应版本 https://ru…

基于SpringBoot的在线视频教育平台的设计与实现(论文+源码)_kaic

摘 要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于在线视频教育平台当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了在线视频教育平台&#xff0c;它彻底改变了过…