当前位置: 首页 > article >正文

基于匿名管道实现的进程池

这是一份基于匿名管道实现的进程池代码,供学习参考

ProcessPool.cc

#include <iostream>
#include <string>
#include <vector>

#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include "Task.hpp"
// master
class Channel
{
public:
    Channel(int wfd, pid_t id, const std::string &name) : _wfd(wfd), _id(id), _name(name)
    {
    }
    int Getwfd()
    {
        return _wfd;
    }
    int Getid()
    {
        return _id;
    }
    std::string &Getname()
    {
        return _name;
    }
    static int NextChannel(int num)
    {
        static int next = 0;
        int ret = next;
        next++;
        return ret % num;
    }
    void Close(){
        ::close(_wfd);
    }
    ~Channel()
    {
    
    }

private:
    int _wfd;
    pid_t _id;
    std::string _name;
};

void clean(std::vector<Channel> &Ch)
{
    for (auto &e : Ch)
    {
        close(e.Getwfd());
    }
    for (auto &e : Ch)
    {
        waitpid(e.Getid(), nullptr, 0);
    }
}

void CreateChannel(std::vector<Channel> &channels, int num, task_t task)
{
    for (int i = 0; i < num; i++)
    {
        int pipefd[2]; // 管道
        if (pipe(pipefd) < 0)
            exit(1);
        pid_t id = fork();
        if (id == 0)
        {
            if (!channels.empty())
            {
                for(auto & channel : channels) channel.Close();
            }
            // worker;
            close(pipefd[1]);   // close w   ---> r
            dup2(pipefd[0], 0); // 重定向

            task();

            exit(0);
        }
        close(pipefd[0]); // w
        channels.emplace_back(pipefd[1], id, "Channel-" + std::to_string(i));
    }
}

void SendTaskCommend(Channel &ch, int task)
{
    write(ch.Getwfd(), &task, sizeof(task));
}
void ctrlProcess(std::vector<Channel> &channels, int num, size_t times = 10)
{
    while (times--)
    {
        //      选择任务
        int task = SelectTask();
        //      选择进程
        int ch = Channel::NextChannel(num);
        //      发送
        SendTaskCommend(channels[ch], task);

        // 回收进程
        sleep(1);
    }
}
int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        std::cout << "Usage: " << argv[0] << "processnum" << std::endl;
        return 1;
    }
    int num = std::stoi(argv[1]);
    std::vector<Channel> channels;

    InitTask();
    // 创建
    CreateChannel(channels, num, worker);
    // 控制,分配任务
    ctrlProcess(channels, num);
    // 回收
    clean(channels);
    return 0;
}

Task.hpp

#pragma once

#include <iostream>
#include <functional>
#include <ctime>
#include <cstdlib>
#include <unistd.h>
#include <sys/types.h>

#define TaskNum 3

// typedef void (*task_t)();
using task_t = std::function<void()>;

void Print()
{
    std::cout<< "I am Print Task" << std::endl;
}
void DownLoad()
{
    std::cout<< "I am DownLoad Task" << std::endl;
}
void Flush()
{
    std::cout<< "I am Flush Task" << std::endl;
}

task_t tasks[TaskNum];

void InitTask()
{
    srand(time(nullptr) ^ getpid());
    tasks[0] = Print;
    tasks[1] = DownLoad;
    tasks[2] = Flush;
}

void ExcuteTask(int num)
{
    tasks[num]();
}
int SelectTask()
{
    return rand() % TaskNum;
}
void worker()
{
    while(true) {
        int command = 0;

        // 卡在read了
        int i = read(0, &command, sizeof(command));
        if(i == 0) {
            std::cout<<getpid()<<"  quit "<<std::endl;
            break;
        }
        ExcuteTask(command);
    }
}


http://www.kler.cn/news/363632.html

相关文章:

  • 关闭或开启Win11系统的自动更新
  • window7虚拟机VMware与主机共享文件
  • 【C++11】右值引用和移动语义
  • uniapp 单表、多级动态表单添加validateFunction自定义规则
  • 富格林:可信操作助力有效追损
  • docker容器无法连接宿主机mysql排查
  • 系统移植相关概念总结
  • 大数据-MySQL集群
  • 使用electron 打包构建cocosCreator 的window exe
  • 鸿蒙应用开发:数据持久化
  • windows 上编译ceres suitesparse
  • #Swift 下标 Subscript - Access the elements of a collection
  • 【C++指南】运算符重载详解
  • 【JAVA毕设】基于JAVA的酒店管理系统
  • Flink SQL+Hudi数据入湖与分析实践
  • Scala的reduce
  • 昆虫种类识别数据集昆虫物种分类数据集YOLO格式VOC格式 目标检测 机器视觉数据集
  • 牛客周赛64(C++实现)
  • 你真的了解Canvas吗--解密十二【ZRender篇】
  • 【AI创新】优化ChatGPT提示词Prompt设计:释放AI的无限潜能
  • 使用AITemplate和AMD GPU的高效图像生成:结合Stable Diffusion模型
  • 数据结构(8.2_1)——插入排序
  • KOC营销崛起:怎样统计每个达人的App推广效果?
  • vscode连接keil-5 开发STM32 程序
  • Windows下搭建VUE开发环境
  • 一文搞定二叉树