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

Linux--进程池

这次,我们来写一个线程池的非常简陋代码,帮助我们理解

我们之前也讲到过:关于C++的池化技术。

进程池是预先创建一组子进程,统一管理任务分配与资源回收的并发模型

什么是进程池?

进程池是预先创建一组空闲进程,统一管理任务队列,避免频繁创建/销毁线程开销的并发编程模型

思路是:

利用父进程管理所有的子进程,而让子进程去完成某种任务!

我们通过匿名管道来实现:

父进程传输信息给子进程,子进程根据父进程传输的信息来执行不同的任务!

简单来说就是:父进程发出指令,由子进程去执行

为什么进程池能够提高效率?

因为OS不相信用户,因此,我们的执行任务的代码中,必定会由大量的系统调用来构成,而上几篇我们讲到,它调用是有成本的!

现在我们采用:预先创建进程,要用时直接拿,而不是需要用到是再去创建进程。同时,在执行完一个任务的子进程还可以继续去执行另外的任务,从而用重复利用的方法提高了资源效率。

我们知道:管理好事物的本质就是:“先描述,在组织!”

创建对象结构体:

class channel
{
public:channel(int comfd, pid_t slaverid, std::string processname): _comdfd(comfd), _slaverid(slaverid), _processname(processname){}// private:
public:int _comdfd;              // 发送任务的文件描述符pid_t _slaverid;          // 子进程的pidstd::string _processname; // 子进程的名字,方便打日志
};

我们操作流程主要有:

初始化

控制进程

关闭进程

int main()
{//模拟执行任务LoadTask(&tasks);//种下随机数种子srand(time(nullptr));// 再组织std::vector<channel> channels;// 初始化,创建多个进程,建立框架!InitSliver(&channels);// Debug(channels);// std::cout<<channels[0]._comdfd<<":"<<channels[0]._slaverid<<":"<<channels[0]._processname<<std::endl;//控制进程ctrlSlaver(channels);QuitSlaver(channels);return 0;
}

模拟执行任务:

#pragma once
#include<iostream>
#include<vector>//自定义函数指针
typedef void(*task_t)();void Task1()
{std::cout<<"检查单词是否有问题"<<std::endl;
}void Task2()
{std::cout<<"检查是否要更新版本"<<std::endl;
}void Task3()
{std::cout<<"查看下载进度"<<std::endl;
}void Task4()
{std::cout<<"查看用户是否需要登录"<<std::endl;
}void LoadTask(std::vector<task_t>* tasks)
{tasks->push_back(Task1);tasks->push_back(Task2);tasks->push_back(Task3);tasks->push_back(Task4);

进程执行任务

void sliver()
{while(true){int cmdcode=0;//读取到cmdcode中int n=read(0,&cmdcode,sizeof(int));if(n==sizeof(int)){std::cout<<"slaver get a command: "<<getpid()<<" comdcode:"<<cmdcode<<std::endl;if(cmdcode>=0 &&cmdcode<tasks.size()){tasks[cmdcode]();}}if(n==0)break;}
}

初始化部分

//输出型参数 *
//输入型参数const &
//输入输出型参数 &
void InitSliver(std::vector<channel>* channels)
{//确保每一个子进程都只有一个写端std::vector<int>oldfd;for (int i = 0; i < 10; i++){int pipefd[2];// 建立管道int n = pipe(pipefd);if (n < 0){perror("pipe");return;}// 创建父子进程pid_t id = fork();if (id < 0){perror("fork");return;}else if (id == 0) // child{for(auto&fd:oldfd)close(fd);close(pipefd[1]); // 关闭一端dup2(pipefd[0], 0);close(pipefd[0]);sliver();std::cout<<"process: "<<getpid()<<" quit"<<std::endl;exit(0);}// fatherclose(pipefd[0]); // 关闭一端std::string processname = "process" + std::to_string(i);channels->push_back({pipefd[1], id, processname});oldfd.push_back(pipefd[1]);// sleep(1);}}

简洁菜单:

void Menu()
{std::cout << "####################################################################" << std::endl;std::cout << "####################################################################" << std::endl;std::cout << "#######1.检查单词是否有问题    2.检查是否要更新版本###################" << std::endl;std::cout << "#######3. 查看下载进度   4.查看用户是否需要登录#######################" << std::endl;std::cout << "##########0.退出####################################################" << std::endl;std::cout << "####################################################################" << std::endl;
} 

控制进程模块:

void ctrlSlaver(const std::vector<channel>& channels)
{int count=0;while(true){int select=0;Menu();std::cout<<"Please Enter# "<<std::endl;std::cin>>select;if(select<=0 ||select>5)break;//选择任务// int cmdcode=rand()%tasks.size();int cmdcode=select-1;//选择进程int processpos=rand()%tasks.size();std::cout<<"father say:"<<"cmdcode:"<<cmdcode<<" already send to "<<channels[processpos]._slaverid<<" process name: "<<channels[processpos]._processname<<std::endl;//发送任务write(channels[processpos]._comdfd,&cmdcode,sizeof(cmdcode));count++;if(count>=5)break;sleep(1);}}

关闭进程

void QuitSlaver(const std::vector<channel>& channels)
{for(const auto e:channels){close(e._comdfd);waitpid(e._slaverid,nullptr,0);}
}

注意:关闭进程这里不能写成这样:

  for(const auto &c : channels) close(c._cmdfd);for(const auto &c : channels) waitpid(c._slaverid, nullptr, 0);

http://www.dtcms.com/a/573902.html

相关文章:

  • 洞头区网站建设收费网站模板制作步骤
  • wordpress直接自己网站怎么做优化
  • 【开题答辩全过程】以 分布式菌菇销售系统为例,包含答辩的问题和答案
  • ui设计网站建设是什么意思深圳做网站制作
  • Canal:让 MySQL 数据同步像呼吸一样自然
  • PE工具开发实战:非正向与安全解析
  • 进一步加强网站建设管理郑州app拉新项目
  • 徐州百度推广总代理台州专业关键词优化
  • C++ 中模板元编程与 SFINAE 机制
  • 【实用运维工具】一键完成Oracle数据库的健康巡检,生成WORD报告
  • ICLR 2025 Spotlight | 打破AI“黑箱”!最新IIS评分框架:揭示模型性能与可解释性的共生关系
  • Java实现国密算法 SM2 /SM3 /SM4(基于 BouncyCastle)
  • 文件网站建设高新公司网站建设哪家好
  • Zabbix企业级分布式监控系统(上)
  • 深度解析:接口性能优化实战指南
  • 站点创建成功html代码hr表示
  • 一、Netty-高并发IO底层原理(5种主要的IO模型)
  • 网站开发外包 验收c2c有哪些网站
  • Jenkins是什么
  • 建网站公司浩森宇特大连网络营销师招聘网
  • LeetCode - 杨辉三角 / 二叉树的最大深度
  • RV1126 NO.39:OPENCV查找图形轮廓并画框
  • 【第1章>第3节】基于FPGA的图像腐蚀处理算法的Verilog实现
  • 西安电子科技大学信息化建设处网站模板建站排版跟没缓存好似的
  • 神经网络—— 学习与感知器(细节补充)
  • tensorflow 图像分类 之一
  • 自己网站上做淘宝搜索引擎网站开发属于什么行业
  • 查询网站备案号网站如何做免费的推广
  • 编写一个DXE driver 提供遍历pcie设备配置空间的protocol
  • 随笔之工作方法的“术”