Linux 进程池小程序

main.cpp

cpp 复制代码
#include"Task.hpp"
#include<iostream>
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
using namespace std;
const int num=10;
vector<task_t> tasks;
class channel
{
public:
    int _cmdfd;           //发送任务的文件符
    pid_t _childpid;      //子进程的pid
    string _process_name;  //子进程的名字
public:
    channel(int cmdfd,pid_t childpid,string process_name)
    :_cmdfd(cmdfd)
    ,_childpid(_childpid)
    ,_process_name(process_name)
    {}
};

void child()//子进程接收任务并执行任务
{
    while(true)
    {
        int taskcode=0;
        ssize_t ret=read(0,&taskcode,sizeof(int));//读取任务编号
        if(ret==sizeof(int))
        {
            cout<<"child alread get a task: "<<getpid()<<" : taskcode : "<< taskcode<<endl;
            tasks[taskcode]();//根据任务编号执行任务
        }
        if(ret==0)
        {
            break;
        }
    }
}
void Initprocesspool(vector<channel> *channels)
{
    vector<int> v;//存储父进程的写端
    for(int i=0;i<num;i++)
    {
        int pipefd[2];
        int ret=pipe(pipefd);
        pid_t id=fork();
        if(id==0)
        {
            //child
            for(auto &it:v) close(it);//当创建子进程时,此时会继承父进程和上一个子进程的管道写端,需要关闭对上一个子进程的写端
            close(pipefd[1]);//关闭写端
            dup2(pipefd[0],0);//将0号文件描述符重定向到管道文件,从0号文件描述符写的信息会被重定向到管道文件
            child();//子进程去执行任务
            close(pipefd[0]);//关闭读端
            exit(0);
        }
        close(pipefd[0]);//关闭读端
        string name="process"+to_string(i);
        channels->push_back(channel(pipefd[1],id,name));//存储子进程的信息
        v.push_back(pipefd[1]);//将父进程的写端插入
    }
}
void Debug(vector<channel> &channels)//打印所有子进程的信息
{
    for(auto it:channels)
    {
        cout<<it._childpid<<" "<<it._cmdfd<<" "<<it._process_name<<" "<<endl;
    }
}
void menu()
{
    cout<<"###############################################"<<endl;
    cout<<"1. 打篮球                               2.踢足球"<<endl;
    cout<<"3. 打羽毛球                            4.打乒乓球"<<endl;
    cout<<"                                       0.退出   "<<endl;
    cout<<"###############################################"<<endl;
}
void ctrlchild(vector<channel>&channels)
{
    while(true)
    {
        int select=0;
        menu();
        cout<<"please choose: ";
        cin>>select;//输入选择的任务序号
        int processpos=0;//进程编号
        int taskcode=select-1;//选择的序号减一才是存储任务的指针数组的下标
        if(select>0&&select<=4)
        {
            cout<<"father say "<<"taskcode: "
            <<taskcode<<"already send to: "<<channels[processpos]._childpid
            <<"process name: "<<channels[processpos]._process_name<<endl;
            ssize_t n=write(channels[processpos]._cmdfd,&taskcode,sizeof(taskcode));//将存储任务的指针数组的下标写入指定的管道文件
        }
        else
        {
            break;
        }
    }
}
void quitprocess(vector<channel>&channels)
{
    for(const auto &it:channels)
    {
        close(it._cmdfd);//关闭所有子进程的读端
        waitpid(it._childpid,nullptr,0);//回收子进程
    }
}
int main()
{
    Loadtask(&tasks);
    vector<channel> channels;
    //初始化
    srand(time(nullptr));
    Initprocesspool(&channels);
    Debug(channels);
    //开始控制子进程
    ctrlchild(channels);
    quitprocess(channels);
    return 0;
}

Task.hpp

cpp 复制代码
#pragma once
#include<iostream>
#include<vector>
using namespace std;
typedef void (*task_t)();
void task1()
{
    cout<<"打篮球"<<endl;
}
void task2()
{
    cout<<"踢足球"<<endl;
}
void task3()
{
    cout<<"打羽毛球"<<endl;
}
void task4()
{
    cout<<"打乒乓球"<<endl;
}
void Loadtask(vector<task_t>*tasks)
{
    tasks->push_back(task1);
    tasks->push_back(task2);
    tasks->push_back(task3);
    tasks->push_back(task4);
}

运行结果:

相关推荐
独角鲸网络安全实验室2 小时前
2026微信小程序抓包全解析:从实操落地到合规风控,解锁前端调试新范式
前端·微信小程序·小程序·抓包·系统代理绕过·https证书严格校验·进程隔离
有谁看见我的剑了?2 小时前
linux 添加硬盘后系统识别不到硬盘处理
linux·运维·服务器
yc_12244 小时前
用 Visual Studio 远程调试 Linux:从零到流畅的完整指南
linux·ide·visual studio
计算机安禾4 小时前
【Linux从入门到精通】第31篇:防火墙漫谈——iptables与firewalld防护指南
linux·运维·php
下一页盛夏花开4 小时前
ubuntu 20中安装QT以后出现红色空心断点
linux·运维·ubuntu
c++之路4 小时前
C++信号处理
开发语言·c++·信号处理
sanshanjianke5 小时前
Thunderobot 911ME 笔记本 Linux 风扇控制研究
linux
故事还在继续吗6 小时前
C++20关键特性
开发语言·c++·c++20
青少儿编程课堂7 小时前
2026青少儿信息素养大赛备赛指南!Python/Scratch/C++备考要点
开发语言·c++·python
旖-旎7 小时前
深搜练习(电话号码字母组合)(3)
c++·算法·力扣·深度优先遍历