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

网站建设服务方案ppt模板体育用品网站模板

网站建设服务方案ppt模板,体育用品网站模板,网页设计提升班,如网站站长如何对付黑客上篇文章:Linux操作系统4-进程间通信2(命名管道进行通信client与server)-CSDN博客 本篇Gitee代码:myLerningCode 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com) 本篇重点:使用匿名管道实现一个简单的进程池 目录 一.…

上篇文章:Linux操作系统4-进程间通信2(命名管道进行通信client与server)-CSDN博客

本篇Gitee代码:myLerningCode · 橘子真甜/Linux操作系统与网络编程学习 - 码云 - 开源中国 (gitee.com)

本篇重点:使用匿名管道实现一个简单的进程池

目录

一. 进程池

二. 子进程执行任务的方法表

三. 创建子进程,并维护好管道的通信

3.1 类SubEndpoint 

3.4 父进程发送信息码

3.3 子进程接收信息码

3.4 创建子进程与管道文件

四. 父进程负载均衡控制子进程执行任务

五. 父进程等待子进程

六. 主函数测试代码 


一. 进程池

        让一个进程去控制多个进程完成我们的任务。这样可以有效的管理进程,提高整个系统的效率。

        这里,我们使用匿名管道简单实现一个进程池,让父进程去控制多个子进程负载均衡完成任务 。

二. 子进程执行任务的方法表

        提前设计好方法表之后,我们只需要启动程序之后将方法表加载好之后,子进程就可以直接调用这些方法去完成任务。

        如果有新的任务需要完成,只需简单的修改加载方法表的代码即可。

方法表的加载测试代码如下:

#include <iostream>
#include <functional>
#include <string>
#include <vector>#include <cstdlib>
#include <cassert>#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <fcntl.h>// 函数指针
typedef void (*func_t)();// 进程的方法
void add()
{std::cout << "id为" << getpid() << "正在执行加法任务" << std::endl;sleep(1); // 模拟该任务花费的时间
}void sub()
{std::cout << "id为" << getpid() << "正在执行减法任务" << std::endl;sleep(1);
}void print()
{std::cout << "id为" << getpid() << "正在执行打印任务" << std::endl;sleep(1); // 模拟该任务花费的时间
}void download()
{std::cout << "id为" << getpid() << "正在执行下载任务" << std::endl;sleep(1);
}// 建立一个任务集合表  func_t
//此处既可以使用函数指针,也可以使用C++自带的function进行包装
void loadTaskFunc(std::vector<std::function<void()>> *funcMap)
{assert(funcMap != nullptr);funcMap->push_back(add);funcMap->push_back(sub);funcMap->push_back(print);funcMap->push_back(download);
}int main()
{std::vector<std::function<void()>> funcMap;loadTaskFunc(&funcMap);for (int i = 0; i < 100; i++){funcMap[i % 4]();}return 0;
}

测试的结果如下:

之后只需要在让父进程负载均衡将这些任务派发给子进程让它们完成这些任务即可。

三. 创建子进程,并维护好管道的通信

3.1 类SubEndpoint 

        为了方便管理子进程和这个子进程的通信管道,我们定义一个类用于保存这两个信息。这样我们就能方便的选择子进程和这个进程的管道进行通信。

代码如下:

class SubEp
{
public:SubEp(int writeFd, pid_t pid): _writeFd(writeFd), _pid(pid){char buffer[64];snprintf(buffer, sizeof(buffer), "process: num[%d]pid[%d]fd[%d]", num++, pid, writeFd);_name = buffer;}public:int _writeFd;      // 该进程的管道文件描述符pid_t _pid;        // 该进程的pidstd::string _name; // 该进程的名称static int num;    // 这是第几个进程
};
int SubEp::num = 1;

3.4 父进程发送信息码

        父进程每一个每一次随机选择一个子进程让这个子进程随机执行一个任务,这样能基本保证子进程的运行是均衡的。

代码如下: 

// 父进程将一个随机信息码发送给一个随机的子进程
void sendTask(const SubEp &process, const int &num)
{std::cout << "send task num: " << num << " to ->" << process._name << std::endl;int n = write(process._writeFd, &num, sizeof(num));assert(n == sizeof(num));(void)n;
}

3.3 子进程接收信息码

        对于子进程来说,子进程从管道中获取来自父进程发送的信息码。根据父进程传递的信息码来判断执行哪一个任务。

        比如父进程向子进程发送了一个1,子进程在方法表中找到下标为1的这个方法并执行这个方法的代码。

 代码如下:

// 子进程接收来自父进程从管道传递过来的信息码
int receiveTask(int readFd)
{int code = 0;ssize_t n = read(readFd, &code, sizeof(code));if (n == 4) // 传递4个字节说明是一个整数return code;return -1;
}

3.4 创建子进程与管道文件

        定义一个函数用于创建所有的子进程,同时维护好各个子进程与父进程之间的关系

代码如下:

#define PROCESS_NUM 5
// 参数分别是子进程集合,方法集合
void creatSubProcess(std::vector<SubEp> &subs, std::vector<func_t> &funcMap)
{for (int i = 0; i < PROCESS_NUM; i++){int fds[2];int n = pipe(fds); // 创建管道文件assert(n = 0);pid_t id = fork();if (id == 0){// 子进程,需要关闭写端close(fds[1]);// 接收来自父进程的信息码并处理任务,如果没有则阻塞等待while (true){int commandCode = receiveTask(fds[0]);if (commandCode >= 0 && commandCode <= funcMap.size())funcMap[commandCode]();else if (commandCode == -1)break;}exit(0);}// 父进程,需要将子进程和其管道信息保存好到subs中close(fds[0]);SubEp sub(fds[1], id);subs.push_back(sub);}
}

四. 父进程负载均衡控制子进程执行任务

        当我们创建好了子进程,以及父子进程之间的管道通信文件之后,我们就可以让父进程去控制子进程进行执行方法表的任务了。

        子进程在被创建之后,此时父进程还没有向子进程发送消息,由于匿名管道文件具有同步和互斥功能。子进程此时会阻塞等待父进程向管道中发送信息,直到收到信息之后子进程才会根据信息执行相应的任务。

代码如下:

void loadBalanceContrl(const std::vector<SubEp> &subs, const std::vector<func_t> &funcMap, int count)
{int subProcessNum = subs.size();int funcNum = funcMap.size();bool flag = (count == 0 ? true : false);while (true){// 1.随机选择一个子进程int subIndex = rand() % subProcessNum;// 2.随机选择一个任务码int taskcode = rand() % funcNum;// 3.将任务码发送相应的子进程进行执行任务sendTask(subs[subIndex], taskcode);if (!flag) // 表明任务还没有结束{count--;if (count == 0) // 任务数量为0,结束break;}sleep(1);}// 依次关闭子进程的管道文件描述符for (int i = 0; i < subs.size(); i++){close(subs[i]._writeFd);}
}

  注意,我们在完成所有的任务之后,需要关闭子进程的文件描述符表。

五. 父进程等待子进程

        子进程完成所有的任务之后,父进程需要等待子进程并获取子进程的进程退出码和进程退出时候的信号。用于获取任务是否完成以及子进程是否异常退出

代码如下:

        

void waitSubProcess(const std::vector<SubEp> &subs)
{int processNum = subs.size();for (int i = 0; i < subs.size(); i++){int status = 0;waitpid(subs[i]._pid, &status, 0);std::cout << "子进程id:" << subs[i]._pid << " 该进程的退出码为:" << ((status >> 8) & 0xff) << " 该进程的退出信号是:" << (status & 0x7f) << std::endl;}
}

对于进程退出的内容可以看这一篇文章:Linux操作系统2-进程控制2(进程等待,waitpid系统调用,阻塞与非阻塞等待)_wait系统调用-CSDN博客

六. 主函数测试代码 

        测试代码如下:

int main()
{srand((unsigned int)time(0));// 1.创建方法表std::vector<func_t> funcMap; // 方法表集合loadTaskFunc(&funcMap);// 创建子进程并维护好管道文件std::vector<SubEp> subs; // 子进程封装creatSubProcess(subs, funcMap);// 负载均衡派发任务int taskCount = 15;loadBalanceContrl(subs, funcMap, taskCount);// 等待子进程waitSubProcess(subs);return 0;
}

测试结果如下:

 

可以看到,父进程成功地将信息随机发送给子进程让其完成我们的任务。


文章转载自:

http://tk6lZbiA.bqdpy.cn
http://15NkFchW.bqdpy.cn
http://PwUEqioX.bqdpy.cn
http://fvJ9NUDR.bqdpy.cn
http://yRowQ1qT.bqdpy.cn
http://JJepNsQ4.bqdpy.cn
http://ElgsPT4o.bqdpy.cn
http://NR96D3gG.bqdpy.cn
http://hMXfpncz.bqdpy.cn
http://3J3QgVWK.bqdpy.cn
http://F60gPnMj.bqdpy.cn
http://h7TqqdPL.bqdpy.cn
http://CGSDBq1Q.bqdpy.cn
http://Uh8SYHxl.bqdpy.cn
http://jKKL1CH0.bqdpy.cn
http://Tg4Z7RI5.bqdpy.cn
http://qhwc8rDR.bqdpy.cn
http://GAtqDN5S.bqdpy.cn
http://9urfGFrm.bqdpy.cn
http://IgR9EX6c.bqdpy.cn
http://Q3WnsCrA.bqdpy.cn
http://q9BKc1Nm.bqdpy.cn
http://BTjLa4KG.bqdpy.cn
http://RKDz2aNZ.bqdpy.cn
http://UpY5fAzw.bqdpy.cn
http://9WUf47ql.bqdpy.cn
http://5WmdGTBQ.bqdpy.cn
http://QhfwuzaW.bqdpy.cn
http://7lRxn9Lp.bqdpy.cn
http://4EaiKK9F.bqdpy.cn
http://www.dtcms.com/wzjs/663204.html

相关文章:

  • ftp网站 免费湖南省交通建设质安监督局网站
  • 做网站威海给网站定位
  • 西安知名网站制作公司2022最新装修效果图
  • 房管局网站建设做网站需要用什么开发软件
  • 集约化网站建设的函西安营销型网站制作价格
  • 宁波网站建设rswl福州seo技巧培训
  • 模板做图 网站东莞做阀门的网站
  • 网站建设保密协议响水做网站的价格
  • 菏泽百度网站建设wordpress 相关文章 插件
  • wordpress网站数据迁移网上购物哪个商城好
  • 制作网站推广网络广告的形式有哪些?
  • 台州网站建设系统电子商务网站特色
  • 网站建设制作设计开发网页设计师就业形势
  • 查询网站所有关键词排名怎么劝客户做网站
  • 江西建设厅网站官网海外公司推广
  • 热门网站太仓做网站
  • 九江便宜做网站个人网站建设联系
  • 建站行业如何快速成第一单官方静态网站模板下载
  • 池州网站建设价格湖南长沙网站建
  • 网站主机选择与优化wordpress注册码
  • 做网站怎样赚钱谁专门做网站安全维护
  • 中国做外贸的网站后台网站模板下载
  • 网站适合移动端乐清做手机网站
  • 西安电商网站制作软文广告经典案例300大全
  • vs做网站需要的插件开源asp学校系统网站
  • 高端网站设计 上海网站运营目标
  • 局域网网站企业网页设计论文
  • 学生做的网站需要备案网络运营外包托管
  • 唐山网站建设推广快速搭建网站框架的工具
  • 做饲料推广哪个网站好建设网站网站设计