Unix进程间通信基础篇
进程间通信最为广泛的是管道的方式,基础的匿名管道只能用于具有亲缘关系之间的进程间的通信,但是现实中的大多数情况却是很多时候需要在不具有亲缘关系的进程之间的通信,例如不同主机之间的进程的通信,毕竟这是一个网络时代,单机已经跟不上时代的发展了。 我们思考这样一个问题,系统中有一个init进程,它的进程标号是1,从理论上来说,它是所有进程的祖先进程,那么,这是不是意味着所有的进程都共有一个祖先?都具有某种亲缘关系?如果真的是这样的话,有名管道的存在就显得很多余了,显然真实的情况并不是这样。 我们说的具有亲缘关系的进程,是指一个进程通过fork或者vfork进程创建之后的进程之间具有某种联系,这种联系是什么呢?进程的创建是一个复杂的过程,包括父进程状态的拷贝,子进程资源的创建等,但是,子进程虽然能够有一份自己的进程空间,有自己独立的栈区堆区资源,但是他仍然与父进程公用着一个内核空间,这个公共用的内核空间,就是他们之间的亲缘关系。因此unix进程通信,父子进程之间考虑的问题就在于怎么通过这个内核空间进行通信操作。 Tips:父子进程之间共享注册的信号行为与打开的文件描述符表,但是父进程创建的线程,子进程拿不到 常见的通信方式大概有如下三种: 父子进程穿过内核,共享留存于文件系统中的某些信息 父子进程共享内核中的某些信息 父子进程有一个双方都能知道的共享内存区,在该内存区进行信息的交换。 上述三种方式中,只有最后一个不涉用户状态到系统内核状态之间的切换,效率最高。但是无论是哪种行为,都需要进行父子进程双方之间的某种同步机制来保证数据的安全性。 下面来讨论一下另一个问题,进程间通信的方式的持续性问题 假如我们有两个进程,具有情缘关系,最简单的通信方式当然是创建一个匿名管道,直接进行通信 那么,当这两个进程消亡的时候,这个匿名管道是否存在?是否会跟着这两个进程一起消亡? 首先来看一下管道的本质是什么? 虽然管道实现形态上是文件,但是管道本身并不占用磁盘或者其他外部存储的空间。在Linux的实现上,它占用的是内存空间,是内核缓冲区。也是伪文件(不占用磁盘空间) 这里我们使用mkfifo命令创建了一个管道,然后通过stat命令查看当前管道的信息,可以看到,这个管道的size是0,相当于没有大小,说明其确实是不占用磁盘空间。 管道是进程之间通信的一种形式,使用该形式时,系统在内核空间找一个缓冲区作为其数据存放地点,交给进程使用,这个空间怎么去找,系统会提供两个文件描述符,即管道的读端与写端,但是系统不会告诉你这个管道的位置,即,即使管道是你自己创建的,你也无法知道该文件的具体位置,要是系统内核愿意让我们知道他某个地方的地址,岂不是很危险,因为我们可能对这个地址进行误操作,一旦操作成功,岂不是内核被我们玩坏了?所以,在内核空间的东西,只会给我们接口去进行操作,不会让我们进行改动其实际内容。 那么现在我们回到持续性的问题上面来: 持续性分三种: 伴随进程持续的IPC:一直存在,直到打开该IPC的最后一个进程关闭它为止【管道】 伴随内核持续的IPC:跟随内核存在,一直到重启或者主动删除它【消息队列,共享内存,信号量】 伴随文件系统的IPC:随文件系统存在,一直到主动删除该IPC为止【文件映射】 (编辑:天瑞地安资讯网_瑞安站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |