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

绍兴网站开发公司dw做的网站如何使用

绍兴网站开发公司,dw做的网站如何使用,title 门户网站建设招标书,兰州网站seo收费标准目录 一、什么是匿名管道#xff1f; 三、创建与使用匿名管道 三、匿名管道的特点 匿名管道的四种情况 匿名管道的五种特性 四、匿名管道的实践应用---进程池 在编程的世界中#xff0c;匿名管道是一种非常重要的通信机制。今天#xff0c;让我们一起来深入探讨一下匿…目录 一、什么是匿名管道 三、创建与使用匿名管道 三、匿名管道的特点 匿名管道的四种情况 匿名管道的五种特性 四、匿名管道的实践应用---进程池 在编程的世界中匿名管道是一种非常重要的通信机制。今天让我们一起来深入探讨一下匿名管道的奥秘。 一、什么是匿名管道 匿名管道是一种在具有亲缘关系的进程间进行单向通信的方式。它主要用于父子进程之间的数据传递。 Linux指令中的 | 就是在使用匿名管道 用于查找当前系统中所有包含字符串 vim 的进程 ps ajx使用 ps 命令获取系统中的进程信息。|竖线 | 是管道符号将前一个命令的输出作为输入传递给下一个命令。grep vim使用 grep 命令在前面获取的进程信息中搜索包含字符串 vim 的行。 可以发现管道是操作系统提供的资源让ps ajx这个进程的输出重定向到这个管道资源然后由另一个进程grep vim 来读取这个管道的内容作为输入以上就是一个简单的进程间使用匿名管道通信的过程。 三、创建与使用匿名管道 在代码中可以通过特定的系统调用来创建匿名管道。一旦创建成功父进程和子进程就可以通过相应的读写操作来进行通信。 1、匿名管道的创建需要通过下面这个系统调用 //返回值成功返回0失败返回-1 int pipe(int fd[2]) //参数fd是输出型参数返回两个fd 这里表示创建一个匿名管道并返回了两个文件描述符一个是管道的读取端描述符 fd[0]另一个是管道的写入端描述符 fd[1]。 注意这个匿名管道是特殊的文件只存在于内存不存于文件系统中。 到此为止也只是一个进程通过系统调用pipe创建了管道如何实现通信呢 我们可以使用 fork 创建子进程创建的子进程会复制父进程的文件描述符这样就做到了两个进程各有两个「 fd[0] 与 fd[1]」两个进程就可以通过各自的 fd 写入和读取同一个管道文件实现跨进程通信了。 管道只能一端写入另一端读出上面这种模式容易造成混乱所以创建子进程后我们需要让管道只能单向通信父子进程根据实际情况各自切断一个读写fd。 父进程关闭读取的 fd[0]只保留写入的 fd[1]子进程关闭写入的 fd[1]只保留读取的 fd[0] 最终实现父进程持有写入fd子进程持有读取fd 单向信道建立完成后两个进程分别通过write、read的系统调用来向管道读写从而实现了进程的通信 匿名管道的通信的单向的半双工所以如果需要父子进程互相通信我们就要再创建一个管道 以上是父子进程的通信的例子那如果是向上面指令 ps ajx | grep vim 通过匿名管道实现通信的原理细节是怎样的呢 在 shell 里面执行 A | B命令的时候A 进程和 B 进程都是 shell 创建出来的子进程A 和 B 之间不存在父子关系它俩的父进程都是 shell继承了shell的文件描述符子进程A、B再通过各自关闭自己的一个文件fd就可以实现A、B进程的单向通信了 所以匿名管道可以实现的具有亲缘关系的进程之间的通信父子、兄弟、爷孙… 三、匿名管道的特点 对于匿名管道我们可以总结出四种情况、五种特性 匿名管道的四种情况 1、正常情况下如果管道没有数据了读端会阻塞等待直到写端写入数据 2、正常情况下如果管道被写满写端会阻塞等待直到读端读取数据 管道是一种临界资源同一时刻只允许一个进程读取或写入 管道的数据被读取后就会标记为失效允许数据写入时覆盖 3、写端关闭读端会一直读取直到读完管道内的数据读端read会返回0表示读到文件结尾 4、读端关闭此时写端再向这个管道写入已经没有意义且浪费系统资源OS会向写端进程发送SIGPIPE(13)信号终止写端进程 匿名管道的五种特性 1、匿名管道仅限于具有血缘关系的进程间通信常用于父子、兄弟 2、匿名管道默认给读写端提供同步机制确保读写操作的正确性和顺序性 同步 两个或两个以上的进程在运行过程中协同步调按预定的先后次序运行。比如A任务的运行依赖于B任务产生的数据。 3、匿名管道是面向字节流的 在匿名管道中数据的传输是连续的没有明确的边界或结构。发送方可以逐个字节地向管道中写入数据接收方可以逐个字节地从管道中读取数据它不需要对数据进行额外的格式化或解析发送方和接收方只需要关注字节的顺序和数量。 4、匿名管道的生命周期是随进程的 管道本质上是通过文件进行通信的也就是说管道依赖于文件系统那么当所有打开该文件的进程都退出后该文件也就会被释放掉所以说管道的生命周期随进程。 5、管道是单向通信的半双工通信的一种特殊情况 半双工通信指数据可以双向交替传输但不能同时双向传输。而管道这种严格的单向通信可以看作是半双工通信的一种更为特殊和受限的情况。 匿名管道的优势 简单易用提供了一种直接的通信方式。高效对于少量、频繁的数据交换非常有效。 应用场景 进程间简单的命令传递和结果反馈。一些需要快速交互的小型任务协调。 四、匿名管道的实践应用---进程池 接下来通过一个进程池demo对匿名管道实践应用 首先什么是进程池呢 进程池是一种用于管理多个进程资源的机制。 具体来说进程池预先创建一定数量的进程并保持它们处于待命状态。当有任务需要执行时直接从进程池中选取一个空闲的进程来处理该任务而不是每次需要执行任务时都临时创建新的进程。 进程池具有以下一些优点 提高效率避免了频繁创建和销毁进程的开销从而提升系统整体性能。资源管理能够更好地控制和管理系统中的进程资源确保资源的合理分配。并发处理能力可以同时处理多个任务提高系统的并发处理水平。 进程池常用于服务器等需要处理大量并发任务的场景通过合理配置进程池的大小和管理策略可以有效地应对高并发的业务需求。 父进程批量创建匿名管道和子进程父进程设为写端子进程设为读端当父进程有任务需要交给子进程时就选取一个管道写入控制指令对应子进程读取数据后根据指令执行特定的任务我们要考虑子进程完成任务的负载均衡可以较为平均的把任务交给子进程 以下是代码 processpool.cc: #include iostream #include string #include vector #include cassert #include unistd.h #include sys/types.h #include sys/wait.h #include Task.hppconst int num 5; static int number 1;//表示通信信道包含控制文件描述符、进程 ID 和名称 class channel { public:channel(int fd, pid_t id) : ctrlfd(fd), workerid(id){name channel- std::to_string(number);}public:int ctrlfd;pid_t workerid;std::string name; };void Work() {while (true){int code 0;ssize_t n read(0, code, sizeof(code));if (n sizeof(code)){if (!init.CheckSafe(code))continue;init.RunTask(code);}else if (n 0){break;}else{// do nothing}}std::cout child quit std::endl; }void PrintFd(const std::vectorint fds) {std::cout getpid() close fds: ;for(auto fd : fds){std::cout fd ;}std::cout std::endl; }// 传参形式 // 1. 输入参数const // 2. 输出参数* // 3. 输入输出参数 void CreateChannels(std::vectorchannel *c) {// bugstd::vectorint old; //记录上一轮创建的管道的写端文件描述符for (int i 0; i num; i){// 1. 定义并创建管道int pipefd[2];int n pipe(pipefd);assert(n 0);(void)n;// 2. 创建进程pid_t id fork();assert(id ! -1);// 3. 构建单向通信信道if (id 0) // child{if(!old.empty())//子进程需要关闭从父进程继承到的之前轮次的写端fd{for(auto fd : old){close(fd);}PrintFd(old);}close(pipefd[1]);dup2(pipefd[0], 0); //将子进程的读端重定向到0Work就不用传参pipe[0]Work();exit(0); // 会自动关闭自己打开的所有的fd}// fatherclose(pipefd[0]);c-push_back(channel(pipefd[1], id));old.push_back(pipefd[1]);// childid, pipefd[1]} }void PrintDebug(const std::vectorchannel c) {for (const auto channel : c){std::cout channel.name , channel.ctrlfd , channel.workerid std::endl;} }void SendCommand(const std::vectorchannel c, bool flag, int num -1) {int pos 0;while (true){// 1. 选择任务int command init.SelectTask();// 2. 选择信道(进程)const auto channel c[pos];pos % c.size();// debugstd::cout send command init.ToDesc(command) [ command ] in channel.name worker is : channel.workerid 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; } void ReleaseChannels(std::vectorchannel c) {// version 2// int num c.size() - 1;// for (; num 0; num--)// {// close(c[num].ctrlfd);// waitpid(c[num].workerid, nullptr, 0);// }// version 1for (const auto channel : c){close(channel.ctrlfd);waitpid(channel.workerid, nullptr, 0);}// for (const auto channel : c)// {// pid_t rid waitpid(channel.workerid, nullptr, 0);// if (rid channel.workerid)// {// std::cout wait child: channel.workerid success std::endl;// }// } } int main() {std::vectorchannel channels;// 1. 创建信道创建进程CreateChannels(channels);// 2. 开始发送任务const bool g_always_loop true;// SendCommand(channels, g_always_loop);SendCommand(channels, !g_always_loop, 10);// 3. 回收资源想让子进程退出并且释放管道只要关闭写端ReleaseChannels(channels);return 0; } 定义了一个 channel 类来表示通信信道包含控制文件描述符、进程 ID 和名称。Work 函数用于子进程不断从标准输入读取指令并进行处理。CreateChannels 函数创建一定数量的管道和相应的子进程并构建单向通信信道同时记录相关信息到 channel 对象并添加到vectorchannel中。PrintDebug 函数用于打印信道的相关信息。SendCommand 函数根据条件选择任务和信道向信道发送任务命令。ReleaseChannels 函数用于释放信道资源包括关闭文件描述符和等待子进程结束。 需要注意的是CreateChannels 中创建了信道和子进程后把子进程写端fdpipefd[0]重定向到了0将子进程的读端重定向到标准输入文件描述符 0之后在 Work 函数中就可以直接从标准输入读取数据而不需要再专门传递管道的读端文件描述符 pipe[0] 了 是因为每个子进程的读端都被重定向到了0当子进程执行Work时就直接从它们各自的文件描述符表中读取0即可因为进程池中的每个子进程原本的读端fd是不同的子进程执行work调用read时就需要不同的文件描述符。 还有一个需要注意的点 CreateChannels中old的作用 在创建新的进程和管道时old用于记录上一轮创建的管道的写端文件描述符。当子进程创建后在子进程中需要关闭之前轮次创建的这些管道写端保证每个管道文件都只有一个写端指向和一个读端指向以确保资源的正确管理和避免干扰。 Task.hpp: #pragma once#include iostream #include functional #include vector #include ctime #include unistd.h// using task_t std::functionvoid(); typedef std::functionvoid() task_t;void Download() {std::cout 我是一个下载任务 处理者: getpid() std::endl; }void PrintLog() {std::cout 我是一个打印日志的任务 处理者: getpid() std::endl; }void PushVideoStream() {std::cout 这是一个推送视频流的任务 处理者: getpid() std::endl; }// void ProcessExit() // { // exit(0); // }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; // 定义对象 定义了任务类型 task_t 为 std::functionvoid()方便表示各种无参数无返回值的任务函数。定义了一些具体的任务函数如 Download、PrintLog、PushVideoStream 等它们输出一些描述信息和当前进程 ID。Init 类负责管理任务集合 在构造函数中初始化任务集合并设置随机数种子。CheckSafe 方法用于检查任务码是否合法。RunTask 方法根据任务码执行相应任务。SelectTask 方法随机选择一个任务码。ToDesc 方法根据任务码返回任务描述字符串。最后定义了一个全局的 Init 对象 init。
http://www.pierceye.com/news/541775/

相关文章:

  • 2.0网站线上建设什么意思做外贸网站哪家的好
  • 网站域名可以更改吗安装wordpress插件目录下
  • 海南省澄迈住房和城乡建设厅网站ui设计师创意平台
  • 青岛网站设计公司排名wordpress 下载主题
  • 外包做网站不满意中级经济师考试成绩查询
  • 苏州企业网站建站系统网页制作基础步骤
  • 新河网站规划电子商务网站流程
  • 免费网站建设免代码杭州建设工程交易平台
  • 网页网站导读怎么做百度问答兼职怎么做
  • wordpress建站环境报喜鸟集团有限公司网页制作
  • 怎么利用网站赚广告费网站开发服务费入什么科目
  • 求网站2021在线观看设计app的软件
  • 百度文库登录入口昆明网站建设优化技术
  • 江苏建设教育协会网站网络营销专员岗位职责
  • 遂宁门户网站建设先进工作单位帮别人做违法网站会判刑吗
  • 设计公司网站套餐怎么样做短视频
  • 化妆品做网站流程什么是网络营销产品
  • windows搭建php网站推荐商城网站建设
  • php网站开发门槛高吗网络推广网站推广
  • 网站推广的8种方法微信怎么开创公众号
  • 大鹏外贸网站建设海口网站网站建设
  • 手表东莞网站建设技术支持信创网站
  • 中小企业为什么要建网站wordpress特效 插件推荐
  • 好的门户网站龙南建设局网站
  • 深圳住房和建设局官网网站设计导航精选最好的设计网站大全
  • 个人备案网站建设方案书网站开发实训教程
  • 周口网站关键词优化重庆招商网
  • 国内优秀网站设计师江西宜春市城市建设档案馆网站
  • 怎么查看网站用的php还是.networdpress博客页修改
  • 企业查询网站wordpress注册没反应