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

简易版的进程池

1.使用匿名管道实现 进程池

#pragma oncetypedef void(*task_t)();void task1()
{cout << "游戏 刷新日志" << endl;
}void task2()
{cout << "游戏 刷新野区" << endl;
}
void task3()
{cout << "游戏 检测软件是否更新,如果需要,就提示用户" << endl;
}
void task4()
{cout << "游戏 用户释放技能,更新用户的HP和MP"<<endl;
}
void Loadtask(vector<task_t> *tasks)
{tasks->push_back(task1);tasks->push_back(task2);tasks->push_back(task3);tasks->push_back(task4);
}//以上是头文件//以下是程序;
//类似于内存池,每次使用都不再向系统申请进程,而是提前储备进程;
#include<cstdlib>
#include<cassert>
#include<time.h>
#include<sys/wait.h>
#include<sys/stat.h>
#include<iostream>
#include<vector>
#include<string>
#include<unistd.h>using namespace std;
#include"main.h"
const int processnum = 5;//子进程数量=5
vector<task_t> tasks;  //任务列表,全局变量//先描述
class channel
{
public:channel(int cmdfd ,pid_t slaverid,const string &processname):_cmdfd(cmdfd),_slaverid(slaverid),_processname(processname){}
public:int _cmdfd;	//发送任务的文件描述符pid_t _slaverid; //子进程的pidstring _processname;//子进程的名字——方便我们打印日志;
};void slaver()
{//read(0);//直接从标准输入读while (true){int cmdcode = 0;int n = read(0,&cmdcode,sizeof(int));//如果父进程不给子进程发任务?就会阻塞等待;if (n == sizeof(int)){//执行cmdcode 对应的任务列表;cout << getpid() << ":cmdcode:" << cmdcode << endl;//查看父进程给子进程派发的任务码;if (cmdcode > 0 && cmdcode < tasks.size()) //满足条件运行函数;tasks[cmdcode]();}if (n == 0){break;}}
}
//函数传参,需要输入型,输出型,输入输出型参数;
//输入:const &: const引用
//输出:用指针
//输入输出:&引用
void InitProcessPool(vector<channel>* channels)
{//1.初始化for (int i = 0; i < processnum; i++){int pipefd[2];//临时空间;int n = pipe(pipefd);assert(!n);//判断是否成功;(void)n;pid_t id = fork();if (id == 0)//子进程读{close(pipefd[1]);dup2(pipefd[0], 0);//重定向,从标准输入中读close(pipefd[0]);slaver();//执行相对应的任务;cout << "process: " << getpid() << "quit" << endl;//打印子进程pid;退出进程;exit(0);}//父进程写入close(pipefd[0]);//添加channel字段;string name = "process-" + to_string(i);channels->push_back(channel(pipefd[1], id, name));}
}
void Debug(const vector<channel> &channels)
{//testfor (const auto& c : channels){cout << c._cmdfd << " " << c._slaverid << " " << c._processname << endl;}
}
void Menu()											//菜单
{cout << "1.刷新日志" << endl;cout << "2.刷新野怪" << endl;cout << "3.检测更新" << endl;cout << "4.更新状态" << endl;cout << "0.退出游戏" << endl;
}
//控制子进程
void ctrlSlaver(const vector<channel>& channels)
{int which = 0;//int cnt = 5;while(true){int select = 0;Menu();                              //手动控制cout << "please Enter@" << endl;cin >> select;if (select <= 0 || select >= 5) break;//select >0 &&select<5//1.选择任务//int cmdcode = rand() % tasks.size();//创造一个随机数,当作任务;int cmdcode = select-1;//2.选择进程(负载均衡:不可以一直给某个进程派发任务,其他进程都闲着,要均衡发展这个叫做负载均衡)1.使用随机数  2.轮转l来实现负载均衡//int processpos = rand() % channels.size();						//随机数//cout << "father say:" << "cmdcode:" << cmdcode << "already send to" << channels[processpos]._slaverid << endl;cout << "father say:" << "cmdcode:" << cmdcode << "already send to" << channels[which]._slaverid << endl;//轮转//3.发送任务//write(channels[processpos]._cmdfd, &cmdcode, sizeof(cmdcode));      //随机数版本write(channels[which]._cmdfd, &cmdcode, sizeof(cmdcode));			  //轮转which++;which %= channels.size();//cnt--;//sleep(1);}
}
void QuitProcess(const vector<channel> &channels)						//退出进程
{for (const auto& c : channels){close(c._cmdfd);}//sleep(5);for (const auto& c : channels) waitpid(c._slaverid, nullptr, 0);   //等待退出//sleep(5);
}int main()
{Loadtask(&tasks);							//加载任务参数;srand(time(nullptr) ^ getpid() ^ 1023);		//种一个随机数种子//再组织vector<channel> channels;//初始化-------bug?————画图就可以看出来,推荐画一下图!!!答:文件描述符随着创建子进程递增;InitProcessPool(&channels);					//初始化Debug(channels);							//测试//2.开始控制子进程ctrlSlaver(channels);						//控制子进程//3.清理收尾QuitProcess(channels);return 0;
}

相关文章:

  • print(“{}{}“.format())
  • 四、SpringMVC实战:构建高效表述层框架(二)
  • leetcode322零钱兑换(背包问题)
  • 图像分割(三)-RGB转HSV后图像分割方法
  • USB学习——12、usb初始化和插拔驱动软件流程大致框架描述
  • HTML静态网页成品作业(HTML+CSS)——美食火锅介绍网页(1个页面)
  • Autodesk Revit产品痛点
  • 力扣1793.好子数组的最大分数
  • 德克萨斯大学奥斯汀分校自然语言处理硕士课程汉化版(第十周) - 自然语言处理应用
  • 基于Django的博客系统之增加手机验证码登录(九)
  • idea intellij 2023打开微服务项目部分module未在左侧项目目录展示(如何重新自动加载所有maven项目model)
  • 使用 Iceberg、Tabular 和 MinIO 构建现代数据架构
  • C++ | Leetcode C++题解之第149题直线上最多的点数
  • 《沃趣 分手后霸道少爷宠爆我》盛大开机典礼
  • 安装MySQL5.7版本步骤遇到问题
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • 2018一半小结一波
  • Flannel解读
  • Javascript编码规范
  • JS实现简单的MVC模式开发小游戏
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • supervisor 永不挂掉的进程 安装以及使用
  • thinkphp5.1 easywechat4 微信第三方开放平台
  • 给新手的新浪微博 SDK 集成教程【一】
  • 为什么要用IPython/Jupyter?
  • 一个项目push到多个远程Git仓库
  • ionic异常记录
  • 函数计算新功能-----支持C#函数
  • ![CDATA[ ]] 是什么东东
  • # Java NIO(一)FileChannel
  • ###项目技术发展史
  • #{}和${}的区别?
  • #WEB前端(HTML属性)
  • #控制台大学课堂点名问题_课堂随机点名
  • $(function(){})与(function($){....})(jQuery)的区别
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • (20)目标检测算法之YOLOv5计算预选框、详解anchor计算
  • (Repost) Getting Genode with TrustZone on the i.MX
  • (附源码)springboot家庭装修管理系统 毕业设计 613205
  • (附源码)springboot美食分享系统 毕业设计 612231
  • (附源码)ssm基于微信小程序的疫苗管理系统 毕业设计 092354
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (六)vue-router+UI组件库
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (原創) 如何動態建立二維陣列(多維陣列)? (.NET) (C#)
  • (转)3D模板阴影原理
  • (转)详解PHP处理密码的几种方式
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • .jks文件(JAVA KeyStore)
  • .NET Core 项目指定SDK版本
  • .net FrameWork简介,数组,枚举
  • .net wcf memory gates checking failed
  • .NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖
  • @Async 异步注解使用
  • @column注解_MyBatis注解开发 -MyBatis(15)