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

看盘神器app百度关键词优化大

看盘神器app,百度关键词优化大,响应式网站字体大小,东莞网站建设网络公司公司Linux——进程池 池化技术进程池信道模拟任务进程退出一个bug 今天我们来学习一下管道的应用——进程池。如果有没看过上一篇管道的小伙伴可以点击这里#xff1a; https://blog.csdn.net/qq_67693066/article/details/136371517 池化技术 我们首先要了解一下池化技术#x… Linux——进程池 池化技术进程池信道模拟任务进程退出一个bug 今天我们来学习一下管道的应用——进程池。如果有没看过上一篇管道的小伙伴可以点击这里 https://blog.csdn.net/qq_67693066/article/details/136371517 池化技术 我们首先要了解一下池化技术 池化技术Pooling在计算机技术中是一种常见的设计模型主要用于优化资源使用和提高性能。其核心理念是提前保存并维护大量资源在一个特定的“池子”中以备不时之需以及重复使用。这样可以显著减少资源创建和销毁的开销从而提高系统的响应速度和效率。 池化技术的主类型 线程池线程池类似于操作系统中的缓冲区概念。它预先创建并管理一定数量的线程这些线程在初始状态下都处于睡眠状态。当有新任务或请求到来时线程池会唤醒一个睡眠线程来处理该任务处理完成后线程再次进入睡眠状态。这样可以避免频繁地创建和销毁线程从而提高性能。 内存池内存池用于管理内存资源。由于分配和释放内存涉及到系统调用这会导致程序从用户态切换到内核态是一个相对耗时的操作。内存池通过预先分配一定大小的内存块并统一管理可以显著减少内存分配和释放的开销。 数据库连接池数据库连接池用于管理数据库连接。由于创建和关闭数据库连接是一个相对耗时的操作数据库连接池通过预先创建并管理一定数量的数据库连接可以显著提高数据库访问的性能。 对象池对象池是一种常见的对象缓存手段。它预先创建并管理一定数量的对象当需要使用对象时直接从对象池中取出而不是重新创建。这样可以减少对象创建和销毁的开销提高对象的访问性能。 池化技术的优点主要包括 提高资源使用效率通过复用已有的资源减少了频繁创建和销毁资源的开销。 降低系统资源消耗通过统一管理资源可以更好地控制资源的使用避免资源的浪费。 提高系统性能通过减少资源创建和销毁的开销以及优化资源的使用可以提高系统的响应速度和性能。 然而池化技术也需要注意一些问题如资源的管理和维护、资源的复用策略、资源的生命周期管理等。此外不同的池化技术需要根据具体的应用场景和需求来选择和使用。 简单一点来说就是“未雨绸缪”计算的池化技术就是当处理某些事务的时候先把对应的资源先准备好到时候可以直接上手处理事务省下了开销资源的时间。 进程池 我们今天要做的是写一个进程池就是提前先创建好一批进程等到有任务来的时候直接可以处理任务 我们首先把架子搭好 #includeiostream #includeunistd.h const int num 5; using namespace std; #includecassertint main() {//创建多个子进程for(int i 0; i num; i){//创建管道int pipefd[2];int n pipe(pipefd);//检查是否创建管道成功assert(n 0);//创建父子进程pid_t id fork();if(id 0) //子进程{//关闭写端close(pipefd[1])}//父进程//关闭读端close(pipefd[0]);} }信道 现在我们创建好了进程但是有个问题我们并不知道什么时候该往哪个进程发配任务现在我们的主进程跟我们创建的进程没有任何的关系这个时候我们就要用信道 通过信道本质上也是一种管道我们主进程就知道该往哪个进程发配任务了。我们可以创建一个类对它进行管理 #includeiostream #includeunistd.h #includecstring #includevector const int num 5; static int channel_number 1; //信道起始数量 using namespace std; #includecassertclass channel { public:channel(int fd,pid_t id):ctrlfd(fd),workid(id){name channel- to_string(channel_number);}int ctrlfd; //读写端的fdpid_t workid; //子进程idstring name; //管道名字 };int main() {vectorchannel channels; //信道//创建多个子进程for(int i 0; i num; i){//创建管道int pipefd[2];int n pipe(pipefd);//检查是否创建管道成功assert(n 0);//创建父子进程pid_t id fork();if(id 0) //子进程{//关闭写端close(pipefd[1])exit(0);}//父进程//关闭读端close(pipefd[0]);channels.push_back(channel(pipefd[1],id)); //往信道写入} }然后我们把创建信道的过程抽象出来形成一个函数 #includeiostream #includeunistd.h #includecstring #includevector const int num 5; static int channel_number 1; //信道起始数量 using namespace std; #includecassertclass channel { public:channel(int fd,pid_t id):ctrlfd(fd),workid(id){name channel- to_string(channel_number);}int ctrlfd; //读写端的fdpid_t workid; //子进程idstring name; //管道名字 };void CreateChannel( vectorchannel *channels) {//创建多个子进程for(int i 0; i num; i){//创建管道int pipefd[2];int n pipe(pipefd);//检查是否创建管道成功assert(n 0);//创建父子进程pid_t id fork();if(id 0) //子进程{//关闭写端close(pipefd[1])exit(0);}//父进程//关闭读端close(pipefd[0]);channels-push_back(channel(pipefd[1],id)); //往信道写入} }int main() {vectorchannel channels; //信道//创建信道CreateChannel(channels);}这里我们规范一下传参方式 传参形式 输入参数const 输出参数*输入输出参数 我们创建一个函数来表示子进程的工作 void Work() {while(true){cout I am running getpid() endl;sleep(1);} }#includeiostream #includeunistd.h #includecstring #includevector const int num 5; static int channel_number 1; //信道起始数量 using namespace std; #includecassertclass channel { public:channel(int fd,pid_t id):ctrlfd(fd),workid(id){name channel- to_string(channel_number);}int ctrlfd; //读写端的fdpid_t workid; //子进程idstring name; //管道名字 };void Work() {while(true){cout I am running getpid() endl;sleep(1);} }void CreateChannel( vectorchannel *channels) //创建信道 {//创建多个子进程for(int i 0; i num; i){//创建管道int pipefd[2];int n pipe(pipefd);//检查是否创建管道成功assert(n 0);//创建父子进程pid_t id fork();if(id 0) //子进程{//关闭写端close(pipefd[1]);//子进程要完成的工作Work();exit(0);}//父进程//关闭读端close(pipefd[0]);channels-push_back(channel(pipefd[1],id)); //往信道写入} }//测试 void PrintChannel(const vectorchannel channels) //输入型参数 {for(auto e: channels){coute.name, e.ctrlfd, e.workidendl;} }int main() {vectorchannel channels; //信道//创建信道CreateChannel(channels);PrintChannel(channels);sleep(10);return 0;}我们可以运行一下看看 此时我们完成了第一步建立信道。 模拟任务 现在我们建立好了信道接下来就是接收主进程给我们的任务就可以了可是子进程如何接收和识别任务呢我们这里规定传不同的数字做不同的任务 首先我们这里先重定向从标准输入读取省略传参 if(id 0) //子进程{//关闭写端close(pipefd[1]);//子进程要完成的工作dup2(pipefd[0],0); //重定向向标准输入读Work();exit(0);}void Work() {while(true){int code 0; //任务代码int n read(0,code,sizeof(code));assert(n sizeof(code)); //要做的任务} }我们可以开一个hpp文件来模拟我们的任务 #pragma once#includeiostream #includefunctional #includevector #include ctime #includeunistd.htypedef std::functionvoid() task_t; //管理任务void Download() {std::cout I am a Download deal with: getpid() std::endl; }void PrintLog() {std::cout I am a log deal with: getpid() std::endl; }void PushVideoStream() {std::cout I am a vdieo deal with: getpid() std::endl; }class Init {public:// 任务码领取相应的任务码做相应的任务const static int g_download_code 0;const static int g_printlog_code 1;const static int g_push_videostream_code 2;// 任务集合std::vectortask_t tasks; public:Init(){tasks.push_back(Download);tasks.push_back(PrintLog);tasks.push_back(PushVideoStream);srand(time(nullptr) ^ getpid());}bool CheckSafe(int code){if (code 0 code tasks.size())return true;elsereturn false;}void RunTask(int code) //运行任务{return tasks[code]();}int SelectTask() //选择任务{return rand() % tasks.size();}std::string ToDesc(int code){switch (code){case g_download_code:return Download;case g_printlog_code:return PrintLog;case g_push_videostream_code:return PushVideoStream;default:return Unknow;}} };Init init; //创建对象我们相应文件的变化 #includeiostream #includeunistd.h #includecstring #includevector const int num 5; static int channel_number 1; //信道起始数量 using namespace std; #includecassert #includeTask.hppclass channel { public:channel(int fd,pid_t id):ctrlfd(fd),workid(id){name channel- to_string(channel_number);}int ctrlfd; //读写端的fdpid_t workid; //子进程idstring name; //管道名字 };void Work() {while(true){int code 0; //任务代码int n read(0,code,sizeof(code));assert(n sizeof(code)); //要做的任务if(!init.CheckSafe(code)) continue;init.RunTask(code);} }void CreateChannel(vectorchannel *channels) {//创建多个子进程for(int i 0; i num; i){//创建管道int pipefd[2];int n pipe(pipefd);//检查是否创建管道成功assert(n 0);//创建父子进程pid_t id fork();if(id 0) //子进程{//关闭写端close(pipefd[1]);//子进程要完成的工作dup2(pipefd[0],0); //重定向向标准输入读Work();exit(0);}//父进程//关闭读端close(pipefd[0]);channels-push_back(channel(pipefd[1],id)); //往信道写入} }void PrintChannel(const vectorchannel channels) //输入型参数 {for(auto e: channels){coute.name, e.ctrlfd, e.workidendl;} }void SendCommand(const std::vectorchannel channels, bool flag, int num -1) {int pos 0;while (true){// 1. 选择任务int command init.SelectTask();// 2. 选择信道(进程)const auto channel channels[pos];pos % channels.size();// debugstd::cout send command init.ToDesc(command) [ command ] in channel.name worker is : channel.workid std::endl;// 3. 发送任务write(channel.ctrlfd, command, sizeof(command));// 4. 判断是否要退出if (!flag){num--;if (num 0)break;}sleep(1);}std::cout SendCommand done... std::endl; }int main() {vectorchannel channels; //信道//创建信道CreateChannel(channels);//PrintChannel(channels);//选择任务,选择信道const bool g_always_loop true;SendCommand(channels, !g_always_loop, 10);//sleep(10);return 0;}我们可以运行一下 进程退出 其实我们想让进程退出就只需要关闭写端就可以了。此时会读到0表示已经读到了文件末尾 所以我们之前写的代码要稍微修改一下 int main() {vectorchannel channels; //信道//创建信道CreateChannel(channels);//PrintChannel(channels);//选择任务,选择信道const bool g_always_loop true;SendCommand(channels, !g_always_loop, 10);//进程退出关闭写端for(const auto channel : channels) //关闭写端{close(channel.ctrlfd);}//sleep(10);return 0; }我们可以把这几行代码封装起来顺便回收子进程 void ReleaseChannels(vectorchannel channels) {for (const auto channel : channels){close(channel.ctrlfd);}//回收子进程for(const auto channel : channels){pid_t rid waitpid(channel.workid,nullptr,0);if(rid channel.workid){coutwait child: channel.workid successendl;}} }int main() {vectorchannel channels; //信道//创建信道CreateChannel(channels);//PrintChannel(channels);//选择任务,选择信道const bool g_always_loop true;SendCommand(channels, !g_always_loop, 10);//进程退出关闭写端ReleaseChannels(channels);//sleep(10);return 0; }我们可以运行一下 一个bug 其实我们之前写的创建管道的代码有一点bug void CreateChannel(vectorchannel *channels) {//创建多个子进程for(int i 0; i num; i){//创建管道int pipefd[2];int n pipe(pipefd);//检查是否创建管道成功assert(n 0);//创建父子进程pid_t id fork();if(id 0) //子进程{//关闭写端close(pipefd[1]);//子进程要完成的工作dup2(pipefd[0],0); //重定向向标准输入读Work();exit(0);}//父进程//关闭读端close(pipefd[0]);channels-push_back(channel(pipefd[1],id)); //往信道写入} }现在我们是结束一个进程回收一个进程就会有问题 void ReleaseChannels(vectorchannel channels) {for (const auto channel : channels){close(channel.ctrlfd);waitpid(channel.workid,nullptr,0); //关掉一个收一个}// //回收子进程// for(const auto channel : channels)// {// pid_t rid waitpid(channel.workid,nullptr,0);// if(rid channel.workid)// {// coutwait child: channel.workid successendl;// }// } }这个时候进程会卡死。这是为什么呢 其实第一次创建子进程时是没有啥问题的 从第二次开始每次创建的子进程会继承上一个文件描述符表的写端 这种情况会一直累积只有最后一个文件只有一个写端。这样会导致我们的信道不会为空子进程读不到0不会退出发生阻塞。 解决方法也很简单第一种我们倒着回收 第二种在新的子进程中关闭多余的文件描述符我们要在创建信道那里做一点小改动 void CreateChannel(vectorchannel *channels) {vectorint tmp; //临时记录用来记录老的fd//创建多个子进程for(int i 0; i num; i){//创建管道int pipefd[2];int n pipe(pipefd);//检查是否创建管道成功assert(n 0);//创建父子进程pid_t id fork();if(id 0) //子进程{if(!tmp.empty()){for(auto fd : tmp){close(fd);}PrintFd(tmp);}//关闭写端close(pipefd[1]);//子进程要完成的工作dup2(pipefd[0],0); //重定向向标准输入读Work();exit(0);}//父进程//关闭读端close(pipefd[0]);channels-push_back(channel(pipefd[1],id)); //往信道写入tmp.push_back(pipefd[1]); //记录老的文件描述符} } void PrintFd(const std::vectorint fds) //用来打印看看关闭了哪些fd {cout getpid() close fds: ;for(auto fd : fds){cout fd ;}cout endl; }
http://www.pierceye.com/news/556534/

相关文章:

  • 网站建设什么时候好豆瓣wordpress
  • 动漫网站设计报告最好的wordpress商城主题
  • 陕西餐饮加盟网站建设如何做一个网站代码
  • 合浦住房和城乡规划建设局网站网页设计培训机构学什么好
  • 做网站需要注意的地方模板ppt
  • 自己建立公司网站自助建站系统
  • 淅川微网站开发wordpress 侧边收起
  • 网站建设企业哪家好乐清站在那儿
  • 网站建设公司人员配置做网站衡水
  • 成都网站建设939seo搜索优化软件
  • 企业网站建设哪家好seo检测
  • 网站建设的案例教程视频教程兴平市住房和城乡建设局门户网站
  • cps推广网站怎么制作网站图片不显示
  • 手机网站设计图尺寸网站里的课程配图怎么做
  • 网站建设贰金手指下拉贰拾烟台酒店网站建设
  • 哈尔滨建设工程信息网站青岛网络宣传
  • 阿里云网站建设部署与发布网站没备案怎么做淘宝客
  • 潍坊建设银行网站珠海新盈科技 网站建设
  • 金华金东区建设局网站wordpress打开乱码
  • 创建一个网站的条件有哪些网站建设知名
  • 网站目录管理模版昆明大型网站建设费用
  • 莆田高端网站建设wordpress 表情没反应
  • 深圳做网站推广哪家好传奇网站模板怎么做的吗
  • 石景山区网站建设网线制作方法及步骤
  • 做网站端口内容无法替换做微信公众号网站
  • 电商网站首页怎么制作做网站用什么语言高效
  • 广州自助建设网站平台天津做网站美工
  • js 捕获网站异常插件网站商城怎么做
  • 北辰网站开发淮北哪有做淘宝网站
  • 建设银行e路通网站室内设计师证需要学哪些课程