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 pipefd2);
(使用它不需要带文件路径和文件名,所以叫做匿名管道)
该参数为 输出型参数
把我们对应的 以读方式和以写方式打开的两个文件描述符以数组的方式给带出来

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
相关推荐
A小辣椒3 小时前
TShark:Wireshark CLI 功能
linux
A小辣椒7 小时前
TShark:基础知识
linux
AlfredZhao9 小时前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao1 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334661 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪1 天前
linux 拷贝文件或目录到指定的位置
linux
大树882 天前
金刚石散热越强,管路越先见顶
大数据·运维·服务器·人工智能·ai
摇滚侠2 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
霸道流氓气质2 天前
领域驱动设计(DDD)在 Spring Boot 微服务中的实践指南
运维·spring boot·微服务
bush42 天前
嵌入式linux学习记录十四、术语
linux·嵌入式