【操作系统】8/35进程间通信

IPC进程间通信

大概有三四种方式。

对于之前的:opt=WNOHANG,表示非阻塞。

进程间通信基本概述:

多个进程之间建立信道,实现跨进程传递收发消息的技术。

socket也是一种进程间通信技术,网络通信也是进程间通信技术。两个进程之间的交互。

各种和系统都有对这类技术的兼容与实现,IPC是进程间通信的缩写。

IPC:匿名管道(PIPE)、有名管道(FIFO)、内存共享映射(MMAP)、信号(SIGNAL)、Unix Domain Socket(本地套接字)、SYSTEMV消息队列、POSIX消息队列。

传统的socket是网卡,但是本地的不走网卡,不走网络层,可以做独立的进程通信,局域网中可以使用,但是传统公网不能用。

消息队列,有两种:SYSTEMV消息队列、POSIX消息队列。但是不提,就是一些函数。

细说进程通信原理

多个进程交互数据,但是进程间通信的位置在哪?

以后的进程通信技术,都要确定位置,一个进程由两块空间:用户、核心。

使用内核层实现进程通信。

进程通信利用的是内核层(共享内存)实现的,用户层不能通信,每个人的用户层都是独立的,互相不能看见。

但是内核层,空间都是一块地址,就有了交互、交换数据的可能。

内核层共享地址。

例如放入一个数据包在内核层,那么其他进程也能看到,用户层就不可能看到,每个人都是独立的。

进程通信基于内核空间共享模式。

匿名管道(PIPE)

管道特征

  1. 数据流通性
  2. 方向性,数据流通是有方向的。
  3. 可以暂存数据内容

综上是最基本的特征。

管道用法

Linux管道创建函数:pipe函数

int pipe(int fds[2]),先定义一个数组,然后把数组传进去。

调用该函数就能创建匿名管道了。

匿名管道的形态及传输过程

两个进程AB,管道是由一个进程创建的,想让两个进程通信,只需要一个进程创建管道即可,而不是两个人都创建。

假设A去创建,调用pipe函数,传入fds数组。

调用之后,就会在两个内核层之间创建:管道缓冲区。

管道缓冲区的数据结构是:环形队列。管道缓冲区的大小:4K。

管道缓冲区怎么用?肯定是读写。

管道有两端,一端是读端,一端是写端。

R端和W端。

数据传出之后呢,有两个数据:fds[0]和fds[1],0是R,1是W。

R指向0,1指向W。读数据用0,写数据用1。

另外一个进程?

首先如果要用管道,就必须得到fds0和1,才能访问;

进程B是不能再次创建管道,这样自己玩自己的,就无法通信了。

我们要通信,必须是两个进程用一个管道,以管道作为媒介进行通信。

那么B如何读到fds变量?你用户层的东西是无法读到的,但是有一种情况是里外的:子进程是可以的,因为直接继承。

也是R指向0,1指向W。

因此!匿名管道只能完成父子进程之间的通信

这也是缺点。你必须继承才行,如果是两个不相干的进程,是不能用匿名管道的。

匿名管道只能完成亲缘进程间通信。

要定好谁来读,谁来写,要确定传输方向。父写子读,还是子写父读。

定好之后,每个进程都是有一个0和一个1的,也就是4个。

定好了之后,例如是父写子读,那么就要关闭父亲的0和孩子的1端。4个砍掉两个,才是真正的实施措施。

管道用完了,一定要关掉!要成习惯,close(fds[1]);

 应该是先pipe,然后再fork。

也就是说,定好了父写,就是父亲传入内容,然后在子进程中,进行读取。

其中bzero就是给初始值进行一个清零。

管道的访问方式:读写端。

要确定:传输方向。

单工、双工、半双工

单工通信:单行道,一个通信方向,方向不可改变。

同一时刻只能非读即写。不允许切换通信方向。

半双工通信:也是单行道,但是不同时刻可以切换方向。

半双工也是单工,可调节单工。

全双工(双工):同一时刻同时读写,socket就是双工。

上行速度、下载速度,就是双工。

管道使用的注意事项(缺点)

  1. 管道销毁释放,管道队列占用内核空间,如何释放?所有访问管道的描述符全部关闭(close)内核会自行释放管道内存
  2. 匿名管道使用时为单工通信
  3. 只支持亲缘进程间通信
  4. 匿名管道数据传输时,采用无格式字节流,用户需要自行封装数据包。

例如,应用层协议包,协议编号、协议类型、确认报文、验证码、消息内容。固定4K

无论消息是什么,但是包大小都相同。

消息类型、消息内容。大概是结构体的样子。

优点:用起来简单,效率高,适合数字通信。

匿名管道使用时的特殊情况(具有普遍意义的)

很多的特殊情况都这4中情况:

  1. 写端未向管道写数据,管道为NULL,读端读取管道阻塞
  2. 读端未读管道数据,管道为满,写端写管道产生阻塞
  3. 写端关闭,读端读取完管道剩余数据后,再次读时,返回0,也就是说,以后读端读到数据是0了,那就说明写端关闭了
  4. 读端关闭,写端向管道写数据,内核向写端进程发送SIGPIPE,杀死写端进程

开发了服务器和客户端,客户端向服务器发送请求数据,而后客户端异常退出了,服务端接收处理请求后,向客户端发送响应,结果服务端也异常退出了,为什么?

服务端是写端,读端关闭了,那么写端也关闭了。服务端就是被SIGPIPE杀死的。

有名管道(FIFO)

也叫命名管道。

命名管道使用要先创建出管道文件:

命令创建:mkfifo xxx

函数创建:mkfifo("xxx", 0064)权限,unlink("xxx")

黑底黄字的文件,是管道文件prw-rw-r--这种。

有名管道将内核缓冲区实体化变为管道文件,多个进程可以利用管道文件的读写,完成进程间通信(无亲缘你关系进程间通信)

有名管道使用逻辑

两个进程:读和写。读写之间有p类型的管道文件,write在open的时候会产生阻塞,写的时候是WRONLY,读的时候是RDONLY,这就相当于两个钥匙。

进程要访问使用管道文件,必须集齐两种访问权限(RD/WR)才可以成功打开管道并使用,否则就会阻塞,阻塞到另外一把钥匙过来为止。等待另一种权限。

但是O_RDWR这种一个人就可以打开。

管道文件

管道文件属于设备文件,dev当中的,与常规文件不同,不可编辑,也不会分配磁盘,它不能存储数据。

打开之后啥也没有,不能编辑、退出,要打开了就得关闭终端。

管道文件与内核缓冲区的关系

管道文件是和内核缓冲区绑定的,管道缓冲区:环形队列、暂存数据、4K大小。

管道文件就是管道缓冲区的指针,所以说不能存东西。

你在R或W的时候都是先通过管道文件,然后到管道缓冲区找到文件,而不是直接对管道进行操作。你都是在操作:管道缓冲区。

p和管道缓冲区bind了。

删除命名管道文件后,对应的管道缓冲区也会被释放。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值