简约网站欣赏,网站建设企划,小程序代理须知,泸州网站建设哪家好#x1f923; 爆笑教程 #x1f449; 《看表情包学Linux》 #x1f525; CSDN 累计订阅量破千的火爆 C/C 教程的 2023 重制版#xff0c;C 语言入门到实践的精品级趣味教程。了解更多#xff1a; #x1f449; 不太正经 的专栏介绍 ← 试读第一章订阅链接 爆笑教程 《看表情包学Linux》 CSDN 累计订阅量破千的火爆 C/C 教程的 2023 重制版C 语言入门到实践的精品级趣味教程。了解更多 不太正经 的专栏介绍 ← 试读第一章订阅链接 《C语言趣味教程》← 猛戳订阅
目录
Ⅰ. 进程间通信IPC
0x00 引入为什么要进程间通信
0x01 进程间通信发展
Ⅱ. 管道PIPE
0x00 引入何为管道
0x01 匿名管道Anonymous Pipe
0x02 管道通信的原理
0x03 管道通信的特点
0x04 系统调用pipe 接口 Ⅰ. 进程间通信IPC
0x00 引入为什么要进程间通信 IPCInter-Process Communication进程间通信 在讲解进程间通信之前我想我们应当首当其冲地去了解下为什么要进程间通信
进程间通信难道是吃饱了撑了吗进程喜欢没事聊两句当然不是
我们在之前讲过 进程之间是具有独立性 的如果进程间想交互数据成本会非常高
因为独立性之本质即 封闭进程们你封闭你的我封闭我的那么进程间的交流可谓是窒碍难行。
进程间的通信说白了就是 数据交互我们需要多进程进行协同处理一件事情。宏观概念
刚才说的是宏观上的概念下面我们来看看具体的、为什么要进行通信
数据传输一个进程需要将它的数据发送给另一个进程资源共享多个进程之间共享资源通知事件一个进程需要向另一个或一组进程发送讯息通知它 (它们) 发生了某种事件比如进程终止时要通知父进程进程控制有些进程希望完全控制另一个进程的执行如 debug 进程此时控制进程希望能够拦截另一个进程的所有陷阱和异常并能够及时知道它的状态改变属于 闭环控制。
因此不要以为进程独立了就是彻底独立有时我们需要双方能够进行一定程序的信息交互。 0x01 进程间通信发展
System V IPC 现在用的已经非常少了更多的用于本地通信。
这已经是历史产物了只讲共享内存共享内存什么的我们就不讲了
因为现在大家都乐于谈论分布式跨主机的东西了。 Ⅱ. 管道PIPE
0x00 引入何为管道
鼠鼠我啊整天生活在下水道捏在管道里阴暗地爬行对管道可是非常熟悉的捏
何为管道管道是 系统中最古老的 IPC 形式
将一个进程连接到另一个进程的数据流称为管道 (Pipe)。
在 中管道分为 匿名管道 和 命名管道。
下面我们先来讲解 匿名管道 (Anonymous Pipe) 0x01 匿名管道Anonymous Pipe
匿名管道是计算机进程间的一种 单工 先进先出通信机制全双工通信 通常需要两个匿名管道。 举个例子假设内存中有两个独立的进程 和 我们想让 之间进行进程间通信。
* 令 先把数据拷贝到磁盘上再让 去读取该数据如下图所示
我们可以通过这个例子明白一个道理通信之前要让不同的进程看到同一份资源。
现阶段我们要学的进程间通信不是如何通信而是先去关注它们是如何看到同一份资源的。
那么在进程通信之前如何做到让进程 先看到同一份资源 呢
资源的不同决定了不同种类的通信方式 而管道就是提供共享资源的一种手段。
我们知道文件在内存和磁盘之间来回切换是非常耗时的因此进程间通信大多都是内存级别的。
即在内存内部重建一块 小区域 进行通信示意图如下
对我们来说我们 echo 一个 hello写到文件中实际上这就算通信了
但是我们要讨论的不是这种通信我们讨论的是内存级的通信 0x02 管道通信的原理
我们在前几章中学了文件描述符 (fd) 的知识点我们将其系统中存在的匿名管道相结合
首先一个进程维护自己进程对应的文件描述符表 file_struct而 file_struct 中有对应的数组。
数字里存的是 struct file* fd_array[]这里面存的就是打开文件的文件指针。
其中 0,1,2 被默认占用这个在之前我们也做过讲解对应 stdin, stdout, stdin这里不再赘述。
如果我们今天打开一个文件OS 为了管理文件需要将磁盘中的文件的属性信息加载到内存里。
对该文件形成 struct file包含了文件的所有属性对应了文件的
① 操作方法 ② file 自己内部的缓冲区
如果我们让该进程 fork 创建一个子进程
在做拷贝时是不需要将 struct file 本身给子进程拷贝一份的。
创建子进程 task_struct 和 file_struct 是需要被拷贝的但是 struct file 是不需要的。
创建进程和我文件有什么关系
这也就是为什么我们创建 fork 子进程之后让父子打印时都会像同一个显示器打印的原因。
结论struct file 一定能找到对应缓冲区的操作方法和 file 自己内部缓冲区。 0x03 管道通信的特点
我们来看看现实生活中的管道管道大部分都是单向的所有的管道都是为了传输资源的。
现实中的管道传输天然气和石油计算机中的管道传输数据
在计算机通信领域的管道如果文件不再是磁盘文件通过特定的接口表征自己的身份。
自己读写数据时就在文件对应的内存缓冲区里完成数据交互我们称该文件为 管道 (pipe) 。
Linux 下一切皆文件因此管道也是文件管道的底层就是基于 struct file 的。
进程间通信管道是单向的传输数据的。单向的原因是因为管道的通信特点就是单向的。
❓ Q A
① 为什么父进程要分别打开读和写因为为了让子进程继承让子进程不用再打开了。 ③ 为什么父子要关闭对应的读写因为管道必须是单向通信的这是操作系统决定的。 ③ 谁决定父子关闭什么读写因为不是由管道本身决定的是由你的需求决定的。
所以对我们来说管道的建立就一定会出现打开两次文件然后父子进程还要关闭 fd。
关闭我们 close 就行但是打开还要我们 open 两次是不是未免太过于麻烦不用担心有 pipe 0x04 系统调用pipe 接口
Linux 给我们提供了 pipe 接口只需调一下 pipe 就会在底层自动把文件以读和写的方式打开。
你会得到两个 fd并且会被写进 pipefd[2] 数组中 #include unistd.h
int pipe(int pipefd[2]); // 数组中分别存储第一次 O_RDONLY 和 O_WRONLY 你可以理解为pipe 内部封装了 open并且它 open 了两次
第一次 open以 O_RDONLY 读的方式打开第二次 open以 O_WRONLY 写的方式打开
最后把读写 fd 分别放在 pipefd 数组的 0 下标和 1 下标中这就帮你创建了一个共享文件。
并且别忘了 pipe 可是系统调用创建文件时就在内核中将文件类型初始化 i_pipe
让它指向的是一个管道文件指向管道信息也就不用和磁盘产生关联了。
当父进程没有写入的时候子进程在等所以父进程写入之后
子进程才能 read会返回到数据子进程打印读取数据要以父进程的节奏为主。 ❓ 思考父进程和子进程读写的时候向显示器写入也是文件是有一定顺序性的。父子进程各自 printf 的时候会有顺序吗 答案是不会。管道内部没有数据reader 就必须阻塞等待read管道内部如果数据被写满此时 writer 就必须阻塞等待write等管道有数据。
完全乱序的地方就是缺乏访问控制管道内部自带访问控制机制。 我们可以使用 CreatePipe 来创建匿名管道并使用 ReadFile 与 WriteFile 函数来对管道进行读写操作其读写操作总是阻塞式的。 新建进程可继承管道句柄读管道时收到一个意味着管道的写端句柄已经关闭。 [ 笔者 ] 王亦优[ 更新 ] 2022.8.2
❌ [ 勘误 ] /* 暂无 */[ 声明 ] 由于作者水平有限本文有错误和不准确之处在所难免本人也很想知道这些错误恳望读者批评指正 参考资料 Creference[EB/OL]. []. http://www.cplusplus.com/reference/. Microsoft. MSDN(Microsoft Developer Network)[EB/OL]. []. . 百度百科[EB/OL]. []. https://baike.baidu.com/. 比特科技. Linux[EB/OL]. 2021[2021.8.31