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
相关推荐
测试员周周4 小时前
【Appium 系列】第16节-WebView-H5上下文切换 — 混合应用的自动化难点
运维·开发语言·人工智能·功能测试·appium·自动化·测试用例
小辰记事本6 小时前
从零读懂RoCEv2数据包构造:从WQE到线缆上的完整旅程
服务器·网络·网络协议·rdma
小鹏linux7 小时前
Ubuntu 22.04 部署开源免费具有精美现代web页面的Casdoor账号管理系统
linux·前端·ubuntu·开源·堡垒机
在角落发呆8 小时前
Linux转发配置:解锁网络互联的核心密码
linux·运维·网络
齐潇宇8 小时前
Zabbix 7 概述与配置
linux·zabbix·监控告警
裴东青10 小时前
10-实战:RuoYi-Cloud的自动化发布
运维·ci/cd·自动化
江公望10 小时前
Ubuntu htop命令,10分钟讲清楚
linux·服务器
哎呦,帅小伙哦10 小时前
Linux 时间:从原子钟到 clock_gettime 的每一面
linux·运维·服务器
sxgzzn10 小时前
新能源场站数智化转型:基于数字孪生与AI的智慧运维管理平台解析
大数据·运维·人工智能
张小姐的猫10 小时前
【Linux】多线程 —— 线程互斥
linux·运维·服务器·c++