进程间通信

问题收集

  1. 为什么需要专门考虑进程间通信这一问题?解决这个问题的发展历史是什么样的?
  2. 进程间通信的一般处理方法有哪些?都是如何实现的?各自的优劣在哪里?适用场景在哪里?

问题的引出:如何使用户态的进程进行通信

众所周知,用户态的进程相互隔离,都具有独立的地址空间,因此无法进行直接通信,需要进入内核态进行访问。
此处的访问,其实本质上是虚拟地址和物理地址之间的重新映射的关系。当然实现起来是十分复杂的。(待确认本质)

不太好的方法:加锁保护的中间文件

其实是通过创建一个文件,来起到中间过渡的效果。为了一致性,需要加锁进行保护。这样做是很容易理解并实现的,但是由于涉及到磁盘访问,因此代价很高。
但有必要介绍一下当打开一个文件的时候,内核的数据结构是什么样的.这对于理解之后的管道有帮助([2]p634):
首先需要明白,内核如何来表示打开的文件? 使用了三个数据结构来表示:

  1. 描述符表(descriptor table). 每个进程都有一个描述符表, 它的表项是由进程打开的文件描述符来索引的. 每个打开的描述符表项指向文件表中的一个表项.
  2. 文件表(file table). 打开文件的集合是由一张文件表来表示的, 所有的进程共享这张表. 每个文件表的表项组成包括当前的文件位置, 引用计数, 以及一个指向v-node表中对应表项的指针. 关闭一个描述符会减少一次引用计数,只有该引用计数减为零的时候, 内核才会删除这个文件表项.
  3. v-node表(v-node table): 与文件表一样,所有进程共享这张v-node表. 每个表项包含了state结构中的大多数信息, 包括st_mode和st_size成员.

Unix进程生命周期开始时, 打开的描述符赋给了stdin(描述符0), stdout(描述符1)和stderr(描述符2). open函数总是返回最低的未打开的描述符.

以下用两个例子说明.
第一个为fd1和fd4个文件描述符, 分别指向不同的文件, 这两个进程没有共享:
在这里插入图片描述
第二个为fd1和fd4两个文件描述符, 通过不同的文件表表项来引用同一个文件.例如,若以同一个filename调用open函数两次, 就会发生这种情况. 这里的关键思想是每个描述符都有它自己的の文件位置,所以对不同的描述符的读操作可以从文件的不同位置获取数据.
在这里插入图片描述
这样我们也能理解父子进程之间是如何进行文件共享的. 假设在调用fork之前, 父进程有如图10-12所示的打开文件, 然后由图10-14 展示了调用fork后的情况. 子进程有一个父进程描述符的副本, 父子进程共享相同的打开文件表集合, 因此共享相同的文件位置.

在内核删除相应文件表表项之前, 父子进程必须都关闭了他们的描述符.

在这里插入图片描述

管道

特点

  1. 半双工单向传输

管道实现进程间通信的本质是什么?

为什么管道通信的双方需要具有同一个父进程?拥有同一个父进程的本质是什么?

fork出来的子进程与父进程共享同一个文件偏移量,即拥有同一个描文件述符,从而能够指向同一个文件。
在fork后处理文件描述符有以下两种常见的情况【1】:

  1. 父进程等待子进程完成。这种情况下,父进程无需对其描述符做任何处理。当子进程结束后,它曾进行过读、写操作的任意共享描述符的文件偏移量已做了相应更新。
  2. 父进程和子进程各自执行不同的程序段。在这种情况下,fork之后,父进程和子进程各自关闭他们不需使用的文件描述符,这样就不会干扰对方使用的文件描述符。折算方法是网络服务进程经常使用的。
进程的创建的本质

此处涉及到了进程的创建,父进程与子进程,进程控制块及其内存布局,父进程与子进程的访问内存方式(写时复制),fork函数的分别在父子进程中的两个返回值,

当执行fork()的时候,具体发生了什么:《深入理解Linux内核(第三版)》p122

参考《Unix环境高级编程(第三版)》p181,《深入理解Linux内核(第三版)》p85

参考:https://www.cnblogs.com/jacklu/p/5317406.html

FIFO(命名管道)

信号量

共享内存区

消息队列

参考文献

[1] 《深入理解Linux内核》
[2] 《Unix核心编程》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值