查看手册(man):
翻译
#include
功能:创建一无名管道
原型
int pipe(int fd[2]);
参数
fd:文件描述符数组,其中fd[0]表示读端, fd[1]表示写端
返回值:成功返回0,失败返回错误代码
视图
#include
#include
#include
#include
#include
#include
#include
#include using namespace std;
int main()
{//1. 创建管道int pipefd[2]={0}; //pipefd[0] 读, pipefd[1]写int n=pipe(pipefd);assert(n!=-1);(void)n; //debug assert , release assert#ifdef DEBUG cout<<"pipefd[0]: "<//子进程//3. 构建单项通道,子进程读取,父进程写入//3.1 关闭子进程不需要的fdclose(pipefd[1]);char buffer[1024];while(true){ssize_t s=read(pipefd[0], buffer, sizeof(buffer)-1);if(s>0){buffer[s]=0;cout<<"Father:"<//3.2 变化的字符串snprintf(send_buffer, sizeof(send_buffer), "%s", message.c_str());//3.3写入write(pipefd[1], send_buffer, strlen(send_buffer));break;}pid_t ret = waitpid(id, nullptr, 0);assert(ret!=-1);(void)ret;return 0;
}
创建多个进程,子进程按找父进程发送的指令执行任务;创建的每个进程的pid和匿名管道fd[1]利用pair包装后用vector存起来。
1. 任务表
using func = std::function;std::vector callbacks; //任务调用(根据下标)
std::unordered_map desc; //任务栏信息
2. 子进程读取命令
int waitCommand(int waitFd, bool &quit) //如果对方不发,我们一直阻塞式等待
3. 父进程唤醒子进程(写入管道,也就是输入指令)
void sendAndWakeup(pid_t who, int fd, uint32_t command)
规定:4字节输入流
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "Task.hpp"using namespace std;int waitCommand(int waitFd, bool &quit) //如果对方不发,我们一直阻塞式等待
{uint32_t command = 0;ssize_t s = read(waitFd, &command, sizeof(command));if (s == 0) //退出{quit = true;return -1;}assert(s == sizeof(uint32_t));return command;
}void sendAndWakeup(pid_t who, int fd, uint32_t command)
{write(fd, &command, sizeof(command));cout << "主进程: 唤醒进程: " << who << " 命令: " << desc[command] << "通过: " << fd << endl;
}#define process_Num 5
int main()
{load();// pid, pipefdvector> slots;//创建多个进程for (int i = 0; i < process_Num; i++){//创建管道int pipefd[2] = {0};int n = pipe(pipefd);assert(n != -1);(void)n;pid_t id = fork();assert(id != -1);//子进程读取if (id == 0){// child//关闭写端close(pipefd[1]);while (true){// pipefd[0]//等命令bool quit = false;int command = waitCommand(pipefd[0], quit); //如果对方不发,我们一直阻塞式等待if (quit)break;//执行命令if (command >= 0 && command < handlerSize()){callbacks[command]();}else{cout << "非法command: " << command << endl;}}exit(0);}// father//父进程写入//关闭读端close(pipefd[0]); // pipefd[1]slots.push_back(make_pair(id, pipefd[1]));}//开始任务 父进程派发任务srand((unsigned long)time(nullptr) ^ getpid() ^ 303200109240139); //让我们的数据源更随机while (true){//选择任务int command = rand() % handlerSize();//选择进程int choice = rand() % slots.size();//布置任务给指定进程sendAndWakeup(slots[choice].first, slots[choice].second, command);sleep(2);// int select;// int command;// cout << "######################################################" << endl;// cout << "# 1. show functions 2.send command #" << endl;// cout << "######################################################" << endl;// cout << "please select> ";// cin >> select;// if (select == 1)// showHandler();// else if (select == 2)// {// cout << "输入你的指令> ";// //选择任务// cin >> command;// //选择进程// int choice = rand() % slots.size();// //布置任务给指定进程// sendAndWakeup(slots[choice].first, slots[choice].second, command);// }// else// {// }}//关闭fd 所有的子进程退出for (const auto &slot : slots){close(slot.second);}//回收所有子进程信息for (const auto &slot : slots){waitpid(slot.first, nullptr, 0);}return 0;
}
#pragma once#include
#include
#include
#include
#include
#include using func = std::function;std::vector callbacks;
std::unordered_map desc;void readMySQL()
{std::cout << "sub process[" << getpid() << "] 执行访问数据库的任务\n" << std::endl;
}void execuleUrl()
{std::cout << "sub process[" << getpid() << "] 执行Url解析\n" << std::endl;
}void cal()
{std::cout << "sub process[" << getpid() << "] 执行加密任务\n" << std::endl;
}void save()
{std::cout << "sub process[" << getpid() << "] 执行数据持久化任务\n" << std::endl;
}//任务表
void load()
{desc.insert({callbacks.size(), "readMySQL: 读取数据库"});callbacks.push_back(readMySQL);desc.insert({callbacks.size(), "execuleUrl: 进行Url解析"});callbacks.push_back(execuleUrl);desc.insert({callbacks.size(), "cal: 执行加密"});callbacks.push_back(cal);desc.insert({callbacks.size(), "save: 执行数据持久化"});callbacks.push_back(save);
}//展示多少任务
void showHandler()
{for (const auto &iter : desc){std::cout << iter.first << "\t" << iter.second << std::endl;}
}//多少方法
int handlerSize()
{return callbacks.size();
}