news 2026/7/1 22:47:34

Linux:简易进程池编写

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux:简易进程池编写
  • 设计概念
  • Channel
  • 初始化
  • 创建任务
  • 子进程工作
  • 轮询方案
  • 分配工作
  • 关闭子进程和管道
  • Main

设计概念

进程池,即我们可以预先创建一堆子进程和对应的管道。等父进程有任务时派发给子进程工作。这样就可以节省开辟进程的花销:

当没有任务时,即管道为空。那么子进程就是阻塞状态不会影响其他进程工作效率。

但是注意我们要将任务均衡地派发给子进程,即实现负载均衡

Channel

首先我们要设计一个方案让父进程能统一管理与子进程之间的管道,最好的方法就是封装一个类。
那么类的成员变量必然要有管道的写端fd、子进程的pid还可以有给子进程的编号。

classChannel{public:Channel(intwfd,pid_t id,conststd::string&name):_wfd(wfd),_subprocessid(id),_name(name){}intGetWfd(){return_wfd;}pid_tGetPidProcessId(){return_subprocessid;}std::stringGetName(){return_name;}//关闭写端voidColseChannel(){close(_wfd);}//等待子进程voidWait(){pid_t rid=waitpid(_subprocessid,nullptr,0);if(rid>0){std::cout<<"wait"<<rid<<"success!"<<std::endl;}}~Channel(){}private:int_wfd;pid_t _subprocessid;std::string _name;};

初始化

接下来我们要初始化Channel数组。
根据要创建的worker个数num,我们可以写一个简单的for循环创建管道和子进程。由子进程关闭写端,父进程关闭读端,即可。
但是我们要注意一个细节,这里以创建两个子进程举例,这里先创建第一个worker:

然后分别关闭读写端:

此时我们创建第二个worker:

然后分别关闭读写端:

这时我们发现第二个子进程对第一个管道的写端并没有关闭,此时有可能造成父进程最后无法结束进程。
因此我们在创建新的worker时,要将前面的worker的写端关闭:

voidCreatChannelAndSub(intnum,std::vector<Channel>*channels,task_t task){for(inti=0;i<num;i++){intpipefd[2]={0};intn=pipe(pipefd);//创建管道失败if(n<0)exit(1);//创建子进程pid_t id=fork();if(id==0){//非空就要关闭前面的写端if(!channels->empty()){for(auto&channel:*channels)channel.ColseChannel();}close(pipefd[1]);//重定向到标准输入dup2(pipefd[0],0);//回调函数task();close(pipefd[0]);exit(0);}//父进程std::string channel_name="Channel-"+std::to_string(i);close(pipefd[0]);channels->emplace_back(pipefd[1],id,channel_name);}}

创建任务

我们来实现不同的任务以分配给子进程,首先重命名下函数指针用以实现回调函数:

随意实现三个简单的任务:

voidPrint(){std::cout<<"I am print task"<<std::endl;}voidDownLoad(){std::cout<<"I am download task"<<std::endl;}voidFlush(){std::cout<<"I am flush task"<<std::endl;}

创建回调表:

分配任务:

intSelectTask(){returnrand()%TaskNum;}

执行任务:

voidExcuteTask(intnumber){if(number<0||number>2)return;tasks[number];}

子进程工作

以及有了上面的一系列任务,我们是时候给子进程工作了:

voidwork(){while(true){intcommand=0;intn=read(0,&command,sizeof(command));if(n==sizeof(int)){std::cout<<"pid is:"<<getpid()<<"handler task"<<std::endl;ExcuteTask(command);}//写端关闭if(n==0){std::cout<<"sub process:"<<getpid()<<" quit"<<std::endl;break;}}}

轮询方案

前面提到我们要实现负载均衡,这里可以简单实现为轮询。即轮流给子进程派送任务:

intNextChannel(intchannelnum){staticintnext=0;intchannel=next;next++;next%=channelnum;returnnext;}

分配工作

子进程的工作也有了,轮询方案也有了,就可以给子进程正是分配工作了:

voidSendTaskCommand(Channel&channel,inttaskcommand){write(channel.GetWfd(),&taskcommand,sizeof(int));}voidctrlProcessOnce(std::vector<Channel>&channels){sleep(1);//挑选任务inttaskcommand=SelectTask();//挑选信道和进程intchannel_index=NextChannel(channels.size());//发送任务SendTaskCommand(channels[channel_index],taskcommand);std::cout<<std::endl;std::cout<<"taskcommand:"<<taskcommand<<"channel:"<<channels[channel_index].GetName()\<<"sub process:"<<channels[channel_index].GetPidProcessId()<<std::endl;}voidctrlProcess(std::vector<Channel>&channels,inttimes=-1){if(times>0){while(times--)ctrlProcessOnce(channels);}else{while(true)ctrlProcessOnce(channels);}}

关闭子进程和管道

有了前面关闭子进程所有写端的处理,我们能直接关闭子进程的读端进而使子进程退出,对子进程等待即可:

voidCleanUpChannel(std::vector<Channel>&channels){for(auto&channel:channels){channel.ColseChannel();channel.Wait();}}

Main

接下来就是在main函数里安排代码执行的顺序,我们还可以通过选项的形式控制生成的子进程数量:

intmain(intargc,char*argv[]){if(argc!=2){std::cerr<<"Usage:"<<argv[0]<<" processnum"<<std::endl;}intnum=std::stoi(argv[1]);std::vector<Channel>channels;//1.创建子进程和信道CreatChannelAndSub(num,&channels,work);//2.控制子进程ctrlProcess(channels,5);//3.回收资源CleanUpChannel(channels);return0;}

来尝试运行代码:

完整代码

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/1 1:05:52

Wan2.2-T2V-A14B在AI音乐MV自动生成中的协同创作模式

Wan2.2-T2V-A14B在AI音乐MV自动生成中的协同创作模式 你有没有想过&#xff0c;一首歌的MV可以完全由AI生成&#xff1f;不是简单的画面拼接&#xff0c;而是真正理解歌词意境、节奏起伏和情感张力&#xff0c;自动构建出具有电影质感的动态影像——从樱花飘落的慢镜头到赛博都…

作者头像 李华
网站建设 2026/6/25 23:37:40

Wan2.2-T2V-A14B模型更新日志解读:v2.2版本带来了什么?

Wan2.2-T2V-A14B模型更新日志解读&#xff1a;v2.2版本带来了什么&#xff1f;在短视频、广告创意和影视预演需求爆炸式增长的今天&#xff0c;内容创作的速度与质量正面临前所未有的挑战。传统视频制作依赖专业团队、高昂成本和漫长周期&#xff0c;而AI生成技术的崛起正在悄然…

作者头像 李华
网站建设 2026/7/1 2:28:28

Wan2.2-T2V-A14B如何实现多角色协同行为的合理编排

Wan2.2-T2V-A14B如何实现多角色协同行为的合理编排 在影视预演、高端广告和数字人协作系统中&#xff0c;一个长期困扰AI生成技术的核心难题是&#xff1a;如何让多个虚拟角色像真实世界一样自然互动&#xff1f;不是简单地把几个人物拼在同一画面里&#xff0c;而是让他们“有…

作者头像 李华
网站建设 2026/7/1 7:44:09

解决C++ Builder中的资源标识符问题

在使用C++ Builder 11.2进行开发时,常常会遇到一些资源文件(.rc文件)中定义的标识符在C++源代码中无法识别的现象。本文将结合实例详细讲解如何解决这一问题,确保你在开发过程中能够顺利使用资源文件中的标识符。 问题描述 假设你有一个名为strings.rc的资源文件,其中包…

作者头像 李华
网站建设 2026/7/1 15:11:28

9 个专科生课堂汇报工具推荐,AI 写作降重神器

9 个专科生课堂汇报工具推荐&#xff0c;AI 写作降重神器 当论文遇上时间&#xff0c;你是否也在挣扎&#xff1f; 对于专科生来说&#xff0c;课堂汇报、论文写作、文献综述这些任务早已成为学习生活中的“常态”。但面对这些任务时&#xff0c;很多人却常常感到力不从心。尤其…

作者头像 李华
网站建设 2026/6/26 18:03:44

高分辨率视频生成难题破解:Wan2.2-T2V-A14B实测报告

高分辨率视频生成难题破解&#xff1a;Wan2.2-T2V-A14B实测报告 在短视频日均播放量突破百亿次的今天&#xff0c;内容生产的速度与质量正面临前所未有的挑战。传统影视制作流程动辄数周、成本高昂&#xff0c;而市场对“即想即得”的创意表达需求却愈发迫切。正是在这种背景下…

作者头像 李华