【Linux】进程池

大致草稿

思维导图

学习目标

一、进程池的代码编写顺序

       在进程池中,我们要创建多个子进程,并且对多个子进程和父进程建立管道的关系,确保父进程和子进程之间可以进行相互通信。

       父进程就是master,而子进程就是work/slaver。大致的工作安排就是:管道中没有数据,worker进程就在阻塞等待任务的到来,而master向哪个管道写入数据,就是唤醒哪个子进程来处理任务,但是父进程要进行后端任务划分的均衡管理。

       对于每一个父进程与子进程之间的联系,我们可以建立一个类来进行描述他们之间的关系,代码如下:

class Channel
{
public:
    Channel(int wfd, int id, std::string name) // 初始化列表
        :_wfd(wfd)
        ,_subprocessid(id)
        ,_name(name)
    {}
    ~Channel()
    {}
private:
    int _wfd; // 写入的端口
    pid_t _subprocessid; // 指向的子进程的编号
    std::string _name;  // 进行连接的名字
};

1.1 创建信道和子进程

       我们可以通过使用主函数的参数来进行获取想要创建的管道数,就是在在主函数中第一个参数表示的是命令中有几个字符串,第二个参数就是存放这些字符串的数组。大致格式就是:

int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        std::cerr << "Usage:" << argv[0] << "processnum" << std::endl;
        return 1;
    }
    ......
}

       由于,在系统中,这种创建的子进程不为1,所有父进程要进行管理起来(先描述,在组织)。在前言,我们可以利用数组来进行管理这个有关管道的类。

std::vector<Channel> Channels;

       因此,现在,让我们开始进行创建信道和子进程,我们先来创建管道,定义一个文件描述符数组,我们将这个文件描述符数组传入管道函数中进行获取读写文件的端口。

int pipefd[2]; // 读端和写端的文件描述符
int n = pipe(pipefd); // 创建管道
if (n < 0)  // 如果返回值小于0,管道创建失败
{
    return;
}

       在创建完管道之后,我们开始创建子进程,但是要注意:在子进程中,不能让子进程不退出,从而导致子进程有进入循环,开始进行创建进程,这样,进程的创建就乱了套。所以,我们要在子进程中进行退出代码的编写。

       在介绍完创建管道和子进程之后,我们要来进行关闭读端或者写端,保证父进程和子进程可以通过管道实现半双工通信。代码如下:

pid_t id = fork();  // 创建子进程
if (id == 0)
{
    close(pipefd[1]);  // 关闭相应的端口
    //dup2(pipefd[0], 0);
    work(pipefd[0]);
    close(pipefd[0]);
    exit(0); 
}

// 3.构建一个名字
std::string channelname = "channel_" + std::to_string(i);
// 父进程
close(pipefd[0]);  // 关闭父进程
// 1.子进程的pid 2.父进程的写端
Channels->push_back(Channel(pipefd[1], id, channelname));

1.2 控制子进程,通过Channel

       在这一部分中,我们将要执行的函数建立一张函数指针数组,我们可以通过函数指针数组的下标来指向一个函数,通过数组的下标来实现函数的功能。

#define TaskNum 3

typedef void (* test_t)(); // 函数指针类型

test_t Tasks[TaskNum];  // 函数指针数组


void Loadtask()  // 加载函数,将函数指针存放在数组中
{
    srand(time(nullptr) ^ getpid() ^ 177777); // 获取当前时间作为随机数种子
    Tasks[0] = print;
    Tasks[1] = download;
    Tasks[2] = flush;
}

void ExcuteTask(int num)  //  启动函数
{
    if(num < 0 || num > 2)
    {
        return;
    }
    Tasks[num]();
}

int slectTask() // 随机发送一个码
{
    return rand() % TaskNum;
}

       因此,我们在利用管道进行控制子进程中,我们可以使用传递数组下标的方式来进行使用相应的子进程完成派遣得到的一些任务。

在控制子进程这一部分,我们可以分为:选择一个任务,选择一个进程,发送任务。

int selectChannel(int channelnum) // 利用循环的方式进行任务的分配
{
    static int next = 0;
    int channel = next;
    next++;
    next %= channelnum;
    return channel;
}

void sendTask(Channel &channel, int taskcommend)
{
    // 向写端发送任务的编号
    // sleep(1);
    write(channel.getwid(), &taskcommend, sizeof taskcommend);
}

// 1 选择一个任务,
int taskcommend = slectTask();

// 2 选择一个进程,
int channelindex = selectChannel(Channels.size());

// 3 发送任务
sendTask(Channels[channelindex], taskcommend);

       这一部分还可以通过控制派遣任务的数量来给子进程分配任务,我们可以将代码进行改编,创建一个新的函数,我们可以在添加一个新的参数来指明派遣任务的数量。

void ctrlProcessOnce(std::vector<Channel> Channels)
{
    sleep(1);
    // 1 选择一个任务,
    int taskcommend = slectTask();
    // 2 选择一个进程,
    int channelindex = selectChannel(Channels.size());
    // 3 发送任务
    sendTask(Channels[channelindex], taskcommend);

    std::cout << "taskcommend:" << taskcommend << ' ' << "channel:" << Channels[channelindex].getname() << ' ' << "to send subprocess:" << Channels[channelindex].getid() << std::endl;
}

void ctrlProcess(std::vector<Channel> Channels, int times = -1)
{
    if (times == -1)
    {
        while (true)
        {
            ctrlProcessOnce(Channels);
        }
    }
    else
    {
        while (times--)
        {
            ctrlProcessOnce(Channels);
        }
    }
}

1.3 回收所有的管道和子进程

这一部分有一个错误,

void cleanChannel(std::vector<Channel> Channels)
{
    for (auto k : Channels)
    {
        k.CloseChannel();
    }

    for (auto k : Channels)
    {
        k.waitChannel();
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

低代码平台如何革新客户管理

引言 在当今快节奏的商业环境中&#xff0c;企业对于客户管理的需求日益增长。同时&#xff0c;随着技术的不断发展&#xff0c;低代码开发作为一种创新的软件开发方法正在逐渐崭露头角。低代码开发为企业提供了一种更快速、更灵活的方式来构建应用程序&#xff0c;使得传统的软…

烧脑的逻辑图又来了,精力绝对不是花费在做图上。

逻辑图设计之所以比较耗费精力&#xff0c;主要是因为它需要进行深入的思考和分析&#xff0c;以确保设计的逻辑正确、完整和可行。以下是一些可能导致逻辑图设计耗费精力的原因&#xff1a; 复杂性&#xff1a;逻辑图设计通常涉及到复杂的业务流程和系统架构。设计师需要理解各…

04-树5 Root of AVL Tree(浙大数据结构PTA习题)

04-树5 Root of AVL Tree 分数 25 作者 陈越 单位 浙江大学 An AVL tree is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more th…

VMware虚拟机安装Ubuntu-Server版教程(超详细)

目录 1. 下载2. 安装 VMware3. 安装 Ubuntu3.1 新建虚拟机3.2 安装操作系统 4. SSH方式连接操作系统4.1 好用的SSH工具下载&#xff1a;4.2 测试SSH连接 5. 开启root用户登录5.1 设置root用户密码5.2 传统方式切换root用户5.3 直接用root用户登录5.4 SSH启用root用户登录 6. 安…

Kali 我来了

Kali 我来了 1、官网下载2、修改密码3、开启SSH远程登录服务4、关闭kali图形化界面 1、官网下载 官方链接: https://www.kali.org/ 下载链接: https://cdimage.kali.org/kali-2024.1/kali-linux-2024.1-vmware-amd64.7z 解压后 直接导入 VmWare 就可使用可爱的小 Kali 了。 …

太阳能智能农业气象站:创新科技引领现代农业革命

TH-NQ14在科技日新月异的今天&#xff0c;现代农业正迎来一场由智能化、精准化、绿色化驱动的深刻变革。太阳能智能农业气象站作为这场变革的先锋力量&#xff0c;以其独特的优势和强大的功能&#xff0c;为现代农业的发展注入了新的活力&#xff0c;并引领着农业生产的未来趋势…

el-date-picker的使用,及解决切换type时面板样式错乱问题

这里选择器的类型可以选择日月年和时间范围&#xff0c;根据类型不同&#xff0c;el-date-picker的面板也展示不同&#xff0c;但是会出现el-date-picker错位&#xff0c;或者面板位置和层级等问题。 源代码&#xff1a; <el-selectv-model"dateType"placeholder&…

【漏洞复现】Check Point 安全网关任意文件读取漏洞(CVE-2024-24919)

0x01 产品简介 Check Point Security Gateways 是 Check Point Sofware 提供的一系列 网络安全Q解决方案。这些解决方案包括下一代防火墙(NGFW)、数据中心安全网关和 A1驱动的量子网关&#xff0c;旨在为企业提供针对复杂网络威胁的先进防护。它们通过集成的威胁防护、统的安全…

微信小程序 npm构建+vant-weaap安装

微信小程序&#xff1a;工具-npm构建 报错 解决&#xff1a; 1、新建miniprogram文件后&#xff0c;直接进入到miniprogram目录&#xff0c;再次执行下面两个命令&#xff0c;然后再构建npm成功 npm init -y npm install express&#xff08;Node js后端Express开发&#xff…

初出茅庐的小李博客之使用立创开发板(ESP32)连接到EMQX Platform【MQTT TLS/SSL 端口连接】

介绍 手上有一块立创开发板&#xff0c;本着不吃灰的原则把它用起来&#xff0c;今天就来用它来连接上自己部署的MQTT服务器进行数据通信。 硬件&#xff1a;立创开发板 开发环境&#xff1a;Arduino IDE Win11 MQTT 平台&#xff1a;EMQX Platform 立创开发板介绍&#xff1…

ChatGPT AI专题资料合集【65GB】

介绍 ChatGPT & AI专题资料合集【65GB】 &#x1f381;【七七云享】资源仓库&#xff0c;海量资源&#xff0c;无偿分享√

OSError: [Errno 117] Structure needs cleaning

一 问题描述 OSError: [Errno 117] Structure needs cleaning: /tmp/pymp-wafeatri 我重新使用SSH登录也会提示这个类似问题 二 解决方法 2.1 尝试删除报错的文件 &#xff08;想直接看最终解决方法的可忽略此处&#xff09; sudo rm -rf /tmp/pymp-wafeatri 此种方法只能保证…

手机怎么投屏?值得收藏的5个投屏软件(2024全新)

在大屏幕上观看自己喜欢的电影、电视节目和其他媒体节目总是一种很棒的体验。因此&#xff0c;如果你正在寻找通过无线网络或USB数据线在windows或mac电脑或笔记本电脑上屏幕镜像、投屏到电脑显示屏上的指南&#xff0c;那么可以花3分钟时间往下看看。在本文中&#xff0c;小编…

现在,所有人都能免费用GPT-4o了!

OpenAI今日官宣&#xff0c;ChatGPT正式向所有用户免费开放&#xff01;所有用户均可以访问定制化GPT、分析图表、询问有关照片的问题以及5月初GPT-4o添加的其他功能。 OpenAI今天在X上发布推文&#xff1a; 「所有ChatGPT免费用户现在都可以使用浏览、视觉、数据分析、文件上…

CSS+Canvas绘制最美星空(一闪一闪亮晶晶效果+流星划过)

1.效果 2.代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><style>body,html {margin: 0;padding: 0;ov…

tree2retriever:面向RAG场景的递归摘要树检索器实现

tree2retriever 面向RAG场景的递归摘要树检索器实现 Recursive Abstractive Processing for Tree-Organized Retrieval Github:https://github.com/yanqiangmiffy/tree2retriever Example import logging import picklefrom tree2retriever.cluster_tree_builder import Clus…

整理GTX收发器示例工程(高速收发器十一)

前文分析了xilinx官方提供的GTX IP示例工程&#xff0c;该代码的结构比较混乱&#xff0c;本文将该代码进行梳理&#xff0c;形成一个便于使用的模块&#xff0c;后续如果要使用多通道的收发器&#xff0c;多次例化某个模块就行了。 下图是官方例程中GTX IP相关模块的RTL视图&a…

Redis用GEO实现附近的人功能

文章目录 ☃️概述☃️命令演示☃️API将数据库表中的数据导入到redis中去☃️实现附近功能 ☃️概述 GEO就是Geolocation的简写形式&#xff0c;代表地理坐标。Redis在3.2版本中加入了对GEO的支持&#xff0c;允许存储地理坐标信息&#xff0c;帮助我们根据经纬度来检索数据。…

万界星空科技MES系统功能介绍

制造执行系统或MES 是一个全面的动态软件系统&#xff0c;用于监视、跟踪、记录和控制从原材料到成品的制造过程。MES在企业资源规划(ERP) 和过程控制系统之间提供了一个功能层&#xff0c;为决策者提供了提高车间效率和优化生产所需的数据。 万界星空科技MES 系统基础功能&am…

美国心理协会(APA)文献去哪里查找下载

今天讲一个关于心理学的数据库——美国心理协会&#xff08;APA&#xff09;数据库 PsycARTICLES&#xff08;心理学全文数据库&#xff0c;简称PA&#xff09;&#xff0c;收录美国心理学协会&#xff08;American Psychological Association&#xff0c;简称APA&#xff09;…