【Linux】进程间通信——匿名管道

为什么要进行进程间通信?

1.数据传输:一个进程需要将它的数据发送给另一个进程,比如我们有两个进程,一个负责获取数据,另一个负责处理数据,这时第一个进程就要将获取到的数据交给第二个进程

2.资源共享:多个进程间共享同样的资源

3.通知事件:一个进程需要给其他进程发送消息,通知他们发生了某种事件

4.进程控制:有些事件需要完全控制另一个进程,比如我们在使用gdb调试时,gdb就是一个进程,它控制了我们要调试的进程

进程之前是有互相传递信息的需求,但是进程之间又是独立的,一个进程不可能去另一个进程的地址空间中取信息,所以这就要求操作系统去提供一块交换数据的空间来供进程之间使用

OS提供空间有不同的样式,这就有了不同的通信方式

1.管道(分为匿名和命名)

2.共享内存

3.消息队列

4.信号量

那么我们就先来谈一谈匿名管道

匿名管道的具体实现

在谈之前,我们要有一些之前的知识作为理论基础,就是父进程创建子进程PCB和文件描述符表是要拷贝一份的,并且里边的值不会进行修改,就相当于浅拷贝;而管理文件的结构体对象不会拷贝。因为前者是跟进程相关的,而后者是跟文件系统相关的。我们把这段话用图来描述就是这样的:

通过这样的操作父子进程就可以看到同一块文件的缓冲区了,这样进程就可以读写了,但是两个文件由读又写容易发生混乱,所以我们一般关掉一个进程的读端,关掉另一个进程的写端,这样就实现了单向通信,就是因为它是单向通信,就像管道一样,所以这样的通信方式就被命名为管道。

pipe创建内存级文件形成管道

我们上面的操作是基于一个实实在在的磁盘文件的,我们必须得这样吗?肯定不是的,OS就提供了一个系统调用负责提供一个内存级的文件它没有名字,只能通过文件描述符来访问,这个系统调用叫pipe()

它的参数是一个输出型参数,就是pipe这个函数把内存级文件的读写文件描述符放到这个数组中,我们来取来用。

并且,规定0下标放的是r方法,1下标放的是w方法

由上面我们可以看出,匿名管道是只能具有血缘关系的进程之间使用,因为文件描述符表是要靠父进程创建子进程拷贝下来的。

pipe的简单使用

那么下面我们就写一段代码来验证上面所说的内容,并且演示管道究竟应该如何使用,下面的代码就是子进程往管道里写,父进程往管道里读

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
void writer(int wfd)
{const char *str = "i am child,this is the ";int cnt = 0;char buffer[128] = {0};while (1){snprintf(buffer, sizeof(buffer), "%s%d message", str, cnt);write(wfd, buffer, strlen(buffer));sleep(1);cnt++;}
}
void reader(int rfd)
{while (1){char buffer[1024] = {0};read(rfd, buffer, sizeof(buffer));printf("I am father,I get a message:%s\n", buffer);}
}int main()
{int pipefd[2] = {0};int n = pipe(pipefd);if (n < 0)return 1;pid_t id = fork();if (id == 0){// 子进程负责wclose(pipefd[0]);writer(pipefd[1]);exit(0);}// 父进程负责rclose(pipefd[1]);reader(pipefd[0]);return 0;
}

匿名管道的四种情况和五种特性

有了上面的一些基本使用,下面我们来演示一下管道的四种情况以及说明五种特性

四种情况

第一种:管道中没有数据,并且子进程不关闭自己的写端,这时父进程会进行阻塞等待,直到管道中有数据

第二种:子进程一直写,父进程不读,但是父进程不关闭读端,当管道被写满时就要进行阻塞等待,直到管道中的数据被读出去才会继续写

我们就让子进程一次写一个字符,看看它一共能写多少个字符

这里printf如果不给换行的话一定要fflush,否则有的打印的东西会在缓冲区中打印不出来

我们可以看到最终是打印到了65536byte,正好是64kb,我们就可以推断出管道的大小是64kb

第三种:子进程不写了并且关掉了写端,这时读端读完了管道中的数据后,read的返回值就为0,这时我们就可以人为的退出了,这和第一种情况是不同的第一种情况是阻塞等待

我们让子进程写10秒就退出,read返回值为0父进程就退出

第四种:让写端一直写,但是读端不读并且关闭读端,这时的结果就是写端也会退出,因为没人读了写就没意义了。

至于说写端是如何退出的呢?其实是收到了退出信号,我们也可以通过wait的方式来看一下退出信号是什么

我们让写端一直写,读端读5秒后退出,然后通过wait的方式获取子进程(写端)的退出信号

五种特性

通过上面的一些介绍,我们就可以总结出管道的五种特性

1.自带同步机制:写满了就不写了,等待读,等待它们之间的同步,读不到就不读了,等待写

2.具有血缘关系的进程间进行通信

3.pipe是面向字节流的:我可以一个字符一个字符的写,同时可以一下读很多个字节,就是说读的次数和写的次数之间是没有关系的,它们是面向管道中的数据的

4.进程退出,管道自动释放,文件的生命周期是随着进程的

5.管道只能单向通信,就是一个写,一个读,这也叫半双工

PIPE_BUF

PIPE_BUF是一个常量,它是由大小的

就是说:每次写入管道的字节数如果小于这个值,那么就认为本次写入是原子的(安全的),就是保证内容是完整的,不会被分割

命令行管道 |

之前我们说的命令 | ,本质上就是这篇博客说的pipe

比如 

就是同时创建三个进程,两个进程之间创建好管道,第一个进程的输出当作第二个进程的输入,第二个进程的输出当作第三个进程的输入,最终效果是睡眠三秒

功能代码:创建进程池

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/43016.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

K8s驱逐场景以及规避方案参考 —— 筑梦之路

Pod 驱逐分为两种情况&#xff1a; 较安全驱逐 & 提高稳定性的良性驱逐 API 发起驱逐&#xff0c;典型案例&#xff1a;kubectl drain Node Not Ready 时&#xff0c;Controller Manager 发起的驱逐 有风险的驱逐 节点压力驱逐 节点磁盘空间不足、内存不足 或 Pid 不足&…

【Threejs进阶教程-着色器篇】3. Uniform的基本用法2与基本地球昼夜效果

Uniform的基本用法2 关于本Shader教程前两篇地址&#xff0c;请按顺序学习本篇使用到的资源用uniform传递纹理代码分析texture类型的uniform在shader中接收uniformtexture2D()处理图片压缩修改wrapS和wrapT 切换成夜景效果切换Mix() 昼夜切换升级改动代码效果分析解决球体分界线…

医疗器械网络安全| 常见安全漏洞与防护措施

医疗器械网络安全顾问​https://link.zhihu.com/?targethttps%3A//www.wanyun.cn/Support%3Fshare%3D24315_ea8a0e47-b38d-4cd6-8ed1-9e7711a8ad5e 一、常见安全漏洞 医疗器械软件在现代医疗体系中扮演着至关重要的角色&#xff0c;然而&#xff0c;随着技术的不断发展&…

关于centos7自带的nginx1.20.1开启https后,XP系统的IE6和IE8无法显示网页的问题

CentOS7自带的nginx-1.20.1是支持HTTP/2和TLS1.3的。 软件包名称&#xff1a;nginx-1.20.1-10.el7.x86_64 CentOS7默认开启了HTTP/2&#xff0c;但没有开启TLS1.3&#xff0c;以及IE6和IE8的https访问。 开启方法&#xff1a; ssl_ciphers HIGH:!aNULL:!MD5;改为ssl_ciphers…

【Word】快速对齐目录

目录标题 1. 全选要操作的内容 → 右键 → 段落2. 选则制表位3. 配置制表符4. Tab键即可 1. 全选要操作的内容 → 右键 → 段落 2. 选则制表位 3. 配置制表符 4. Tab键即可

36.哀家要长脑子了!--前缀和差分

前缀和 1.一维的795. 前缀和 - AcWing题库 前缀和公式 s[i] a[1] a[2] a[3] ... a[i] 即 s[i] s[i-1] a[i] #include<iostream> using namespace std;const int N 1e5 10; int a[N], s[N];int main(){int m, n;cin >> n >> m;for(int i 1; i <…

Elasticsearch基础(三):Elasticsearch核心原理介绍

文章目录 Elasticsearch核心原理介绍 一、基本概念 1、集群&#xff08;cluster&#xff09; 2、节点&#xff08;node&#xff09; 3、索引&#xff08;index&#xff09; 4、类型&#xff08;type&#xff09; 5、映射&#xff08;mapping&#xff09; 二、 Elastic…

LabVIEW开发高灵敏静电计

开发了一套基于LabVIEW平台的高灵敏静电计控制软件&#xff0c;用于提升闪烁薄膜探测器在中子和伽马射线探测中的灵敏度标定精度。传统的标定方法存在数据准确性不高和操作复杂性高的问题&#xff0c;因此开发这款软件解决这些挑战&#xff0c;通过自动化控制和高效的数据处理&…

Windows下载、配置Java JDK开发环境的方法

本文介绍在Windows电脑中&#xff0c;安装JDK&#xff08;Java Development Kit&#xff09;&#xff0c;也就是Java开发工具包的详细方法。 JDK是Java软件开发的基础&#xff0c;由Oracle公司提供&#xff0c;用于构建在Java平台上运行的应用程序与组件等&#xff1b;其已经包…

[C++]入门基础(1)

Hello大家好&#xff0c;今天通过本篇文章&#xff0c;我们来初步学习C&#xff0c;C可以说是对C语言的一个升级&#xff0c;我们会一步一步的由浅入深的学习C。 目录 1.第一个C程序 2.命名空间 2.1 命名空间出现的意义 2.2 namespace的定义 2.3 命名空间的使用 3.C输入…

亚信安全:《2024云安全技术发展白皮书》

标签 云计算 安全威胁 云安全技术 网络攻击 数据保护 一句话总结 《云安全技术发展白皮书》全面分析了云计算安全威胁的演进&#xff0c;探讨了云安全技术的发展历程、当前应用和未来趋势&#xff0c;强调了构建全面云安全防护体系的重要性。 摘要 云安全威胁演进&#xff…

c#第五次作业

目录 1. 实现通用打印泛型类&#xff0c;可以打印各个集合中的值&#xff0c;方便调试 2. 计算遍历目录的耗时 3. 有哪些算术运算符&#xff0c;有哪些关系运算符&#xff0c;有哪些逻辑运算符&#xff0c;有哪些位运算符&#xff0c;有哪些赋值运算符 1&#xff09;算术运算…

电商数据仓库

目录 1.数据仓库的数据来源为业务数据库&#xff08;mysql&#xff09; 初始化脚本 2.通过sqoop将mysql中的业务数据导入到大数据平台&#xff08;hive&#xff09; 在hive中建立映射的数据库 导入数据 3.通过hive进行数据计算和数据分析 形成数据报表 补全用户信息表中的…

【密码学】流密码的基本概念

在介绍流密码之前&#xff0c;我们先来弄明白一个基础前置知识点——异或运算。 一、异或运算&#xff08;XOR&#xff09; 运算规则&#xff1a;相同为0&#xff0c;不同为1 特点&#xff1a;一个比特进行两次异或运算&#xff0c;可以恢复成原来的比特。 明文&#xff1a;110…

降Compose十八掌之『飞龙在天』| Layout

公众号「稀有猿诉」 原文链接 降Compose十八掌之『飞龙在天』| Layout 页面布局是GUI应用开发的核心&#xff0c;决定着一个UI具体如何实现。今天将延着路线图来练习『降Compose十八掌』的第二招式&#xff0c;学习一下如何使用Compose中的布局来构建页面。 基础骨架 基…

Jenkins教程-15-常用插件-Blue Ocean

上一小节我们学习了Jenkins定时任务构建的方法&#xff0c;本小节我们讲解一下Jenkins常用插件Blue Ocean的使用方法。 Blue Ocean 提供了一套可视化操作界面来帮助创建、编辑 Pipeline 任务。 Blue Ocean 特性&#xff1a; 流水线编辑器&#xff1a;用于创建贯穿始终的持续交…

游戏软件缺少d3dx9_42.dll怎么修复?五种方法助你轻松解决

D3DX9_42.dll的丢失是一种常见的操作系统异常问题&#xff0c;由于日常使用电脑时的不当操作&#xff0c;可能会导致一些dll文件的丢失&#xff0c;D3DX9_42.dll就是其中之一。对于这种情况&#xff0c;我们可以通过谨慎的修复来解决。以下是一种科学的解决D3DX9_42.dll丢失的方…

小白学C++(第一天)基础入门

温馨提醒&#xff1a;本篇文章&#xff0c;请各位c基础不行的童鞋不要贸然观看 C的第一个程序 第一个关键字namespace namespace 是定义空间的名字的关键字&#xff0c;使用格式格式如下&#xff1a; namespace 空间名 { } 其中{ }内的命名空间的成员&#xff0c;可以定义…

初识数组!

目录 1.概念 2.一维数组的创建和初始化 1&#xff09;数组创建 2&#xff09;数组的初始化 3&#xff09;数组的类型 3.一维数组的使用 1) 数组下标 2) 数组元素的打印 3) 数组的输入 4.一维数组在内存中的存储 5.sizeof计算数组元素个数 6.二维数组的创建 1.概念 …

【qt】获取主机信息系统

话不多说,先一睹芳颜! 如果你也想达到这种效果,那咱们就开始吧! 目录 一.登录界面设计1.ui登录设计 二.加载界面1.lineEdit的密码输入模式2.lineEdit按回车跳转的信号3.密码的判断4.创建加载界面5.创建定时器来进行进度条的移动6.定时器执行的槽函数 三.主机信息界面1.主机信息…