Linux - 进程间通信(1)

目录

一、进程为什么要通信

二、进程如何通信

[a. 进程间通信,成本可能会稍微高一点(因为进程是具有独立性的)](#a. 进程间通信,成本可能会稍微高一点(因为进程是具有独立性的))

b.进程间通信的前提,是先让不同的进程看到同一份资源(即"一段内存")

三、进程通信的常见方式

1、匿名管道

1)理解匿名管道

2)使用匿名管道

[3)demo -- 测试管道接口](#3)demo -- 测试管道接口)

[a. 获取的两个fd](#a. 获取的两个fd)

[b. 读一半、写一半](#b. 读一半、写一半)

[c. 管道的4种情况](#c. 管道的4种情况)

[I、如果管道内部是空的 && write fd没有关闭,读取条件不具备,读进程会被阻塞](#I、如果管道内部是空的 && write fd没有关闭,读取条件不具备,读进程会被阻塞)

[II、管道被写满 && read fd 不读且没有关闭,管道被写满,写进程会被阻塞](#II、管道被写满 && read fd 不读且没有关闭,管道被写满,写进程会被阻塞)

[III、管道一直在读 && 写端关闭了wfd,读端 read 返回值会读到0,表示读到了文件结尾](#III、管道一直在读 && 写端关闭了wfd,读端 read 返回值会读到0,表示读到了文件结尾)

IV、rfd直接关闭,wfd一直在进行写入

[d. PIPE_BUF](#d. PIPE_BUF)


一、进程为什么要通信

进程也是需要进行某种协同的 ,且所有协同的前提条件 -- 就是通信

a. 数据传输:一个进程需要将它的数据发送给另一个进程
b. 资源共享:多个进程之间共享同样的资源。
c. 通知事件:一个进程需要向另一个或一组进程发送消息,通知它(它们)发生了某种事件(如进程终止 时要通知父进程)。
d. 进程控制:有些进程希望完全控制另一个进程的执行(如Debug进程),此时控制进程希望能够拦截另 一个进程的所有陷入和异常,并能够及时知道它的状态改变。
子进程继承父进程的数据不属于进程间通信,因为一次通信和一直能通信是不一样的!!
且子进程也仅仅是只读

二、进程如何通信

a. 进程间通信,成本可能会稍微高一点(因为进程是具有独立性的)

b.进程间通信的前提,是先让不同的进程看到同一份资源(即"一段内存")

  1. 一定是某一个进程先需要通信,让OS创建一个共享资源

  2. OS必须提供很多的系统调用(因为操作系统不能被外部直接使用)

OS创建的共享资源的不同,系统调用接口的不同 --- 进程间通信会有不同的种类

三、进程通信的常见方式

system V标准 -- 本地通信
a. 消息队列
b. 共享内存
c. 信号量
可不可以直接复用内核代码直接通信呢??
有的 --- 管道!
管道分为两种,即命名管道和匿名管道

1、匿名管道

1)理解匿名管道

一个进程分别以读方式和写方式打开时,它会生成两份struct file结构体,当我们fork一个子进程时,子进程会将父进程的PCB和文件描述符表都拷贝一份,因为 进程是具有独立性的
但是struct file它是和父进程共用的,因为struct file属于文件系统, 进程需要保持独立性, 和文件无关
理解现象:
为什么父子进程会向同一个显示器终端打印数据??
因为指向的是同一个文件缓冲区
进程默认会打开三个标准输出:0 1 2 --- 怎么做到的?因为 所有的进程默认都是bash的子进程 --- 即bash打开了,则所有的进程也就默认打开了,只需要做好约定即可

关于 close();
为什么我们的子进程主动close(0/1/2),不影响父进程继续使用显示器文件呢??
因为struct file内部也会存在一个引用计数(内存级的),(当子进程close时,ref_count--) 只有当引用计数为0时(ref_count==0),我们才真正的释放文件资源

2)使用匿名管道

int pipe(int pipefd[2]);
(使用它不需要带文件路径和文件名,所以叫做匿名管道)
该参数为 输出型参数
把我们对应的 以读方式和以写方式打开的两个文件描述符以数组的方式给带出来

1.如果我们想要双向通信呢??
创建两个管道
2.为什么要单向通信??
为了 让其实现起来简单 --> 只让它进行单向通信(也因此叫做管道)
3.父进程既然要关闭不需要的fd,那为什么曾经还要打开呢??
为了 让子进程继承下去
可以不关闭吗??
可以的,但是建议关了,以 防万一误写、误读

3)demo -- 测试管道接口
a. 获取的两个fd


b. 读一半、写一半


在管道中,不会出现这种情况

c. 管道的4种情况
I、如果管道内部是空的 && write fd没有关闭,读取条件不具备,读进程会被阻塞

--- wait 等待读取条件具备,再写入数据

II、管道被写满 && read fd 不读且没有关闭,管道被写满,写进程会被阻塞

--- 管道被写满,写条件不具备 --- wait 写条件具备(即读取)

III、管道一直在读 && 写端关闭了wfd,读端 read 返回值会读到0,表示读到了文件结尾
IV、rfd直接关闭,wfd一直在进行写入

写端进程会被OS直接使用13号信号关掉,相当于进程出现了异常

d. PIPE_BUF
相关推荐
卷卷的小趴菜学编程2 分钟前
Linux第一讲--基本的命令操作
linux·运维·服务器
hcja66637 分钟前
CVE-2024-23897-Jenkins任意文件读取漏洞复现
运维·web安全·网络安全·中间件·jenkins
最后一个bug1 小时前
页高速缓存与缓冲区缓存的应用差异
linux·c语言·arm开发·单片机·嵌入式硬件
wingaso2 小时前
[Linux]el8安全配置faillock:登录失败达阈值自动锁定账户配置
linux·运维·安全·ssh
linux修理工2 小时前
speedtest For Ubuntu/Debian
linux·运维·服务器
Steps-of-time2 小时前
Linux之NetLink学习笔记
linux·笔记·学习
vortex52 小时前
Linux 命令行十六进制编辑器:高效操作二进制文件
linux·运维·编辑器
半夏知半秋3 小时前
rust学习-rust中的格式化打印
服务器·开发语言·后端·学习·rust
mcharleylei3 小时前
Centos 安装docker
linux·docker·centos
jerry-894 小时前
系统安全及应用
linux·运维·服务器