系统编程--进程间通信
这里写目录标题
- 简介
- 原理
- 方法
- 管道
- 简介
- pipe函数
- 介绍
- 代码
- 二级目录
- 一级目录
- 二级目录
- 二级目录
- 二级目录
- 一级目录
- 二级目录
- 二级目录
- 二级目录
- 一级目录
- 二级目录
- 二级目录
- 二级目录
简介
原理
父子进程,对于0到3G的区域,是用户段,映射到内存中是各自独立的
而3G到4G的区域,是内核段,映射到内存中是同一块内存地址空间,而既然是在同一块内存地址空间下,就说明二者可以进行通信,进行数据交流、共享
而进程间通信,简称IPC
方法
我们在两个进程之间搭建一个桥梁,或者一个共享区,进行进程间通信(如上图),而具体的实现方式,有下面常用的四种:
管道
简介
管道只能作用于有血缘关系的进程之间,我们可以使用pipe这个函数来创建一个管道,或者在命令行使用命令:mkfifo f1
但是其本质上是一个伪文件,不是真正存在磁盘空间中的文件,他实际上是一个内核缓冲区
其内部实现是一个队列,是一个循环队列,借助内核缓冲区实现,他在两端分别有一个读端和一个写端
(socket也就是一个伪文件)
局限性:
管道必须两个端,读端和写端都准备好了,才可以进行数据通信,其中任何一个进程无法单方面决定数据的通信
且管道由于是一个循环队列,其数据不可以反复读取,一旦读走,管道中的数据不再存在(虽然借助缓冲区实现,缓冲区的数据是可以重复读的,但是由于使用了队列机制,所以无法进行反复读取)
且管道是一个双向半双工,半双工,就是数据只能单方向流动,无法同时进行双向通信,但是由于其流动方向可以改变,所以是双向半双工
(socket是双向全双工)
最后一个就是,只有在有公共祖先的进程,或者说有血缘关系的进程之间才能使用管道
总结:
pipe函数
介绍
代码
由前面可知,父子进程之间会共享全局变量、栈区、…的内容,所以,在fork()执行之后,前面的变量,子进程仍然可以使用
而在fork之前,已经使用fd[2]+pipe()创建出了一个管道,并把他的读端和写端存在了fd数组里,其中,fd[0]是读端,fd[1]是写端
而fork之后,子进程也会有fd[2],如上图
而我们需要将其加工成如下图:
代码:
父进程中,我们关闭读端,让父进程写数据,写完之后,将写端关闭
子进程中,我们关闭写端,接收父进程数据,写到屏幕上,读完之后,将读端关闭