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

医院建设网站网站建设软件

医院建设网站,网站建设软件,php网站开发课程,素材下载平台网站源码进程间通信一、进程间通信1.1 通信的介绍1.2 通信的目的1.3 通信的分类二、管道2.1 匿名管道2.1.1 pipe2.2.2 读写特征2.2.3 命名管道一、进程间通信 1.1 通信的介绍 通信就是一个进程把数据传递给另一个进程,但是每个进程都具有独立性。通信的本质:OS需…

进程间通信

  • 一、进程间通信
    • 1.1 通信的介绍
    • 1.2 通信的目的
    • 1.3 通信的分类
  • 二、管道
    • 2.1 匿名管道
      • 2.1.1 pipe
      • 2.2.2 读写特征
      • 2.2.3 命名管道

一、进程间通信

1.1 通信的介绍

通信就是一个进程把数据传递给另一个进程,但是每个进程都具有独立性。通信的本质:OS需要直接或者间接给通信双方的进程提供“内存空间”,并且要通信的进程,必须看到一份公共的资源

1.2 通信的目的

数据传输: 一个进程需要将它的数据发送给另一个进程
资源共享: 多个进程之间共享同样的资源
通知事件: 一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止时要通知父进程)
进程控制: 有些进程希望完全控制另一个进程的执行(如Debug进程)

为什么要进行通信?

因为我们有时需要多进程协同,例如管道。

1.3 通信的分类

1️⃣ 采用标准的做法:System V进程间通信(聚焦在本地通信,如共享内存)、POSIX进程间通信(让通信过程可以跨主机)。
2️⃣ 采用文件的做法:管道-基于文件系统(匿名管道、命名管道)

二、管道

我们把从一个进程连接到另一个进程的一个数据流称为一个“管道”

我们知道要进行通信要指向同一块空间,所以我们可以让父进程打开一个文件,然后创建子进程,这样父子进程就会指向同一个文件,这样就可以在同一分文件中进行交流。
在这里插入图片描述

两个进程看到同一份资源,让一个进程写,另一个进程读,就可以完成进程间通信,这个文件成为管道文件

但是我们知道往文件里写就要与磁盘进行IO,效率大大降低。

任何一个文件包括两套资源:1.file的操作方法 2.有属于自己的内核缓冲区,父进程可以向对应的文件的文件缓冲区写入,子进程可以通过文件缓冲区读取,此时就完成了进程间通信,这种方式提供的文件称为管道文件。管道文件本质就是内存级文件,不需要IO。

这种管道叫做匿名管道。

2.1 匿名管道

我们知道我们如果以读的方式打开文件,那么子进程也会默认为读方式打开。
所以我们分别以读写方式打开同一个文件,子进程也会继承读写。接下来我们关闭一个进程的读端,再关闭另一个进程的写端(当然也可以不关,但为了防止其他进程使用,还是建议关闭),这样就让不同的进程看到同一份文件。
在这里插入图片描述
一般而言,管道只能用来进行单向数据通信。

那么怎么创建一个管道级文件呢?

2.1.1 pipe

在这里插入图片描述
它的参数是一个输出型参数,它可以帮我们分别以读和写的方式打开文件,然后把文件描述符填进数组返回

#include <iostream>
#include <unistd.h>
#include <cassert>using namespace std;int main()
{int fds[2];int n = pipe(fds);assert(n == 0);printf("fds[0] = %d\nfds[1] = %d\n", fds[0], fds[1]);return 0;
}

在这里插入图片描述
注意 0是读,1是写

至此我们成功创建了管道文件,打开了读写端。

#include <iostream>
#include <unistd.h>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <sys/wait.h>
#include <sys/stat.h>using namespace std;int main()
{// 创建管道文件int fds[2];int n = pipe(fds);assert(n == 0);// forkpid_t id = fork();if(id == 0)// 子{// 子进程通信close(fds[0]);// 关闭读int cnt = 0;while(1){char buf[1024];snprintf(buf, sizeof(buf), "child->father: %s[%d]", "子进程发送", ++cnt);write(fds[1], buf, strlen(buf));sleep(1);}exit(0);}// 父进程通通信close(fds[1]);// 关闭写while(1){char buf[1024];ssize_t s = read(fds[0], buf, sizeof(buf) - 1);if(s) buf[s] = '\0';// 补'\0'cout << "收到消息@ " << buf << endl;}waitpid(id, nullptr, 0);return 0;
}

在这里插入图片描述

2.2.2 读写特征

1️⃣ 读快写慢

子进程休眠,管道内没有数据,此时默认会直接阻塞当前正在读取的进程。

在这里插入图片描述
在这里插入图片描述
读完一次数据后,第二次就会卡在read处等待。

2️⃣ 读慢写快

写端一直在写,读端不读,而管道是有大小的,会被写满

在这里插入图片描述
在这里插入图片描述
当我们让父进程只等待两秒时:
在这里插入图片描述
他会按照指定的大小读取(sizeof(buf) - 1)。

3️⃣ 写关闭,读到0
在这里插入图片描述
4️⃣ 读取关闭,写入

如果是关闭读端,OS会终止写端,并会给写进程发送信号终止进程

在这里插入图片描述

管道特征:

1.管道的生命周期随进程,进程退出,管道释放
2.管道可以用来进行具有血缘关系的进程间通信(常用于父子通信)
3.管道是面向字节流的
4.半双工—单向通信(特殊)
5.互斥与同步机制——对共享资源进行保护的方案

2.2.3 命名管道

我们知道匿名管道只能在有血缘关系的进程间进行通信。
那么没有关系的进程之间就要用命名管道。
可以使用FIFO文件来做这项工作,它经常被称为命名管道,命名管道是一种特殊类型的文件

使用mkfifo命令创建命名管道

在这里插入图片描述
在这里插入图片描述
一个进程往管道文件中写入,另一个进程从管道中读取。就完成了进程间的通信。
在这里插入图片描述
在这里插入图片描述
这里要注意,往管道文件中写入和读取的时候大小一直为0

两个进程打开同一个文件:第二个文件不需要继续创建struct_file对象,直接指向第一个文件的struct_file。在内核中,此时就看到了同一份资源,有着操作方法和缓冲区,不需要把数据刷新到磁盘上去,不需要IO。所以无论是匿名还是命名,本质都是管道。

因为命名管道是通过让不同的进程打开指定名称的同一个文件(因为路径+文件名具有唯一性)。

创建自己的管道文件
我们先创建一个管道文件,首先要让两个进程看到同一份文件。comm.hpp
创建管道文件函数:
在这里插入图片描述
comm.hpp

#include <string>#define NAME_PIPE "./mypipe"using namespace std;bool creatfifo(const string& path)
{int n = mkfifo(path.c_str(), 0666);if(!n) return true;else{cout << "errno mkfifo" << endl;return false;}
}

test1.cc

#include "comm.hpp"using namespace std;int main()
{bool flag = creatfifo(NAME_PIPE);assert(flag);return 0;
}

在这里插入图片描述
删除管道文件
删除管道文件函数:
在这里插入图片描述
comm.hpp

void Delete(const string& path)
{int n = unlink(path.c_str());assert(n == 0);
}

test1.cc

int main()
{bool flag = creatfifo(NAME_PIPE);assert(flag);Delete(NAME_PIPE);return 0;
}

创建和删除管道文件已经完成,我们就可以开始通信了。
test1.cc

#include "comm.hpp"int main()
{bool flag = creatfifo(NAME_PIPE);assert(flag);int rfd = open(NAME_PIPE, O_RDONLY);// 只读if(rfd < 0) exit(1);// readchar buf[1024];while(true){ssize_t s = read(rfd, buf, sizeof(buf) - 1);if(s > 0){cout << "test1->test2# " << buf << endl;}else if(s == 0){cout << "test2 quit, me too!" << endl;break;}else{cout << "error" << endl;break;}  }close(rfd);Delete(NAME_PIPE);return 0;
}

test2.cc

#include "comm.hpp"int main()
{int wfd = open(NAME_PIPE, O_WRONLY);// 只写方式打开同一份文件if(wfd < 0) exit(1);// writechar buf[1024];while(true){cout << "输入: ";fgets(buf, sizeof(buf), stdin);// 从键盘读取ssize_t n = write(wfd, buf, sizeof(buf));assert(n == strlen(buf));}close(wfd);return 0;
}

在这里插入图片描述

http://www.dtcms.com/wzjs/17465.html

相关文章:

  • cdr 做网站超级seo外链工具
  • 西安网站建设 北郊福州seo外包公司
  • 做淘宝优惠劵网站服务器配置宁德市属于哪个省
  • 单页面网站怎么做的站长之家查询工具
  • 中国建设银行网站怎么解绑设备2023年5月疫情爆发
  • 五莲网站建设维护推广万网注册域名
  • 陶瓷 中企动力 网站建设企业qq官网
  • 义乌搜客网络科技有限公司西安seo代运营
  • 在网站上找到漏洞之后怎么做深圳seo优化方案
  • 北京天通苑网站建设怎样开网站
  • 刘晓忠 网站建设什么平台免费推广效果最好
  • 卡通风格网站欣赏2023疫情最新情况
  • 做网站banner图必备的湖州seo排名
  • 如何在百度上做公司网站上海网站seo快速排名
  • 企业网站开发需求分析全国疫情地区查询最新
  • 如何做国际网站产品宣传唯尚广告联盟app下载
  • 公司建设网站成果预测什么是搜索引擎优化的核心
  • 中国医院建设协会网站网络营销推广的特点
  • 做调查的网站知乎谷歌网页版登录入口
  • 舆情监控一般多少钱公众号seo排名优化
  • 柳州做网站的公司有哪些重庆森林经典台词梁朝伟
  • 网站运营与建设作业怎么做宣传推广
  • 淮安网站制作百度指数如何分析
  • 公司网站建设要求书网站源码建站
  • 企业查询网页版成都百度推广和seo优化
  • 嘉兴高端网站百度推广开户联系方式
  • 网站原型是产品经理做职业技能培训班
  • 佛山响应式网站中国域名网官网
  • 在线做汉字头像的网站网络优化工程师吃香吗
  • 企业微信后台管理系统优化标题关键词技巧