
目录
匿名管道的应用: 进程池
进程池(process pool)
先把进程创建出来,需要什么任务 ,派发什么任务.
让一个进程(master进程) ,给其他进程(work进程)派发任务

下面实现process pool
第一步: 创建并初始化processpool
master要管理所有的管道 创建channel
创建管道 ,创建子进程 ,用vector管理全部的channel
#include<iostream>
#include<unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include<vector>
#include<functional>//执行任一方法
//typedef std::function<void()> work_t;
using work_t =std::function<void()>;//定义了函数对象类型
enum
{
OK=0,
UsageError,
PipeError,
ForkError,
CloseError,
Dup2Error
};
//先描述
class channel
{
public:
channel(int wfd ,pid_t who):_wfd(wfd),_who(who)
{
_name ="channel-"+std::to_string(wfd)+"->"+ std::to_string(who);
}
~channel()
{
}
std::string Name()
{
return _name;
}
private:
int _wfd;
std::string _name;//channel-3->203444
pid_t _who;
};
void Worker()
{
//read ->stdin
}
void Download()
{
//read ->stdin
}
//channels是输出型参数
//work_t work 回调方法 使创建子进程与让子进程执行任务是解耦的
int InitProcessPool(std::vector<channel>& channels ,int num ,work_t work)
{
//创建指定进程个数
for(int i=0 ;i <num; i++)
{ //管道
int Pipefds[2]={0};
int n =::pipe(Pipefds);
if(n< 0) return PipeError;
//子进程
pid_t id =::fork();
if(id == 0)
{//child 读
int close_ret = ::close(Pipefds[1]);//关闭写通道
if(close_ret < 0) return CloseError;
int dup2_ret =::dup2(Pipefds[0] ,0);//重定向,让子进程从标准输入中获取要执行的任务。不再使用Pipefds[0]了
if(dup2_ret< 0) return Dup2Error;
work();
::close(Pipefds[0]);
//sleep(10); DebugPrint用
::exit(0);
}
else if(id < 0)
{
return ForkError;
}
else
{//parent
int close_ret = ::close(Pipefds[0]);//关闭读通道
if(close_ret < 0) return CloseError;
channels.emplace_back(Pipefds[1] , id);
}
}
return OK;
}
void DebugProcesspool(std::vector<channel>& channels)
{
for( auto &c :channels)
{
std::cout<< c.Name() <<std::endl;
}
}
void Usage(std::string process)
{
std::cout<<"Uasge:"<< process <<"process-num"<<std::endl;
}
//我们自己是master
int main(int argc ,char* argv[])
{
if(argc!=2)
{
Usage(argv[0]);
return UsageError;
}

最低0.47元/天 解锁文章

被折叠的 条评论
为什么被折叠?



