栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

传统的Unix进程间通信-概述

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

传统的Unix进程间通信-概述

对于多用户、多进程的操作系统来说,进程间通信(IPC)是一项非常重要、甚至必不可少的基本手段和设施。在一个多进程操作系统所提供的运行环境下,可以通过两种不同的途径,或者说采用两种不同的策略,来建立起复杂的大型应用系统。一种途径是通过一个孤立的、大型的、复杂的进程提供所需的功能。早期的操作系统往往倾向于前者,而Unix及其衍生的各种系统则倾向于后者。这种基本方法和策略的改变正是Unix操作系统在程序设计领域中引起革命性转变的结果。相比之下,后者这种方法具有很大的好处:

  • 首先,这种途径使应用软件更加模块化,每个进程所执行的程序可以分别地设计、实现、调试和维护。
  • 其次,由于每个进程都有其独立的地址空间,而相互间的通信则通过明确定义的进程间通信手段和界面来完成,因而使得各个进程都得到保护,在相当程度上排除了相互干扰的可能性,从而增加了系统的可靠性和稳定性。
  • 而且,这种途径还改善了系统规模的可扩展性。例如,在多处理器系统中,这些进程可以在不同的处理器上运行。推而广之,这些进程还可以在多台计算机上运行,并且这些计算机并不非得是在同一个地域。从而形成分布式处理的概念。
  • 最后,就像用7个音符可以组合出无数动听的旋律一样,用若干可执行程序也可以灵活地搭建出很复杂、功能很强的新应用。从这个角度来看,这种途径既促进了软件的模块化,也提供了软件的复用性。

当然,取得这些好处的是有代价的,这种途径也有缺点。首先,从全局来看,这种途径要占用更多的资源,并且增加了CPU运行时的系统开销,使得总体上的运行效率可能会有所下降。其次,由于每个进程都独立地接受调度,使得进程运行时的时序在某些情况成为问题,需要通过一些特殊的进程间通信手段才能保持同步。最后,这种途径要求操作系统提供充分的进程间通信的手段和设施。但是,这些都只是前进路上所遇到的问题。相比之下,这种途径的有点远远超过其缺点,而且随着硬件技术的进步(如内存容量、处理器速度等等),第一条缺点实际上已经微不足道了。事实上,随着应用软件的日益复杂和规模的日益庞大,通过孤立、大型、复杂的单进程途径来实现应用所需的功能往往已经不现实了。

由此可见,进程间通信在现代操作系统中起着至关重要的作用。可以这样说,没有Unix的进程间通信手段就不会有所谓Unix环境,即Unix独特的运行环境和程序设计环境。从另一个角度来说,同任何一种新技术的出现一样,一旦人们认识到上述途径及其对进程间通信手段的需求,这些手段就一定会应运而生。

那么,Unix(从而linux)向应用软件提供一些什么样的进程间通信手段呢?这里也有个发展过程。早期的Unix提供了以下一些手段:

  • 管道(pipe)。父进程与子进程之间,或者两个兄弟进程之间,可以通过系统调用建立起一个单向的通信管道。但是。这种管道只能由父进程来建立,所以对于子进程来说是是静态的,与生俱来。管道两段的进程各自都将该管道视作一个文件。一个进程往管道中写的内容由另一个进程从管道中读取,通过管道传递的内容遵循先入先出(FIFO)的规则。每个管道都是单向的,需要双向通信时就要建立起两个管道。
  • 信号(signal)。读者已经在前面看到过信号的运用。严格说来,signal这种手段并不是专为进程间通信而设置的,它也用于内核与进程之间的通信(不过内核只能向进程发送信号,而不能接收信号)。一般来说,signal是对中断这种概念在软件层次上的模拟(所以亦称软中断),其中信号的发送者相当于中断源,而接收者则相当于处理器,所以必须是一个进程。就像在多处理器系统中一个处理器通常都能向另一个处理器发出中断请求一样,一个进程也可以向其他进程发出信号,此时信号就成了一种进程间通信的手段。
  • 跟踪(trace)。一个进程可以通过系统调用ptrace读写其子进程地址空间中的内容,从而达到跟踪子进程执行的目的。

这几项进程间通信手段都只能用于父进程与子进程之间,或者两个兄弟进程之间。信号的使用虽然并未限制父子进程之间,但发送信号时需要用到对方的pid,而一般只有父子进程之间才知道对方的pid,所以实际上还是只能用于父子进程之间。另一方面,对于子进程来说管道机制静态的,跟中则是单向的。在实际使用中,常常需要在并非这些近亲的进程之间动态地建立通信管道,所以后来增设了一种新的管道:

  • 命令管道(named pipe)。命名管道以FIFO文件的形式出现在文件系统中,所以任何进程都可以通过使用其文件名打开该管道,然后进行读写。这样,管道的使用就不再局限于近亲之间了。从这个意义上说,命名管道是管道的推广。
  • 报文(message)队列。一个进程可以通过系统调用设立一个报文队列,然后任何进程都可以通过系统调用向这个队列发送消息或从队列接手消息,从而以进程间报文传递(message passing)的形式实现通信。
  • 共享内存。一个进程可以通过系统调用设立一片共享内存区,然后其他进程就可以通过系统调用将该存储区映射到其用户地址空间中。此后,就可以像正常的内存访问一样读写该共享内存了。共享内存时一种快速而有效的进程间通信手段,但是并不像其他一些手段那样,可以在一旦写入后就唤醒正在睡眠中等待读取的进程,所以常常要与其他手段配合使用。
  • 信号量(semaphore)。前面讲过内核中使用的信号量机制,而系统V进程间通信手段中的信号量则将这种机制推广到了用户空间。
  • 插口(socket)。从语义的角度来说,socket与命名管道是很相似的,但其重要之处在于socket不仅可以用来实现同一台计算机上的进程间通信,还可以用来实现分布于不同计算机中的进程通过网络进行的通信。这样,就提供了一种统一的、更为一般的进程间通信模式。如果说命名管道把管道这种原来只适用近亲的手段推广到了同一台计算机中的任意进程之间,则socket又进一步将其推广至计算机网络中的任意进程之间。从这个意义上讲,socket成了最一般、最普通适用的进程间通信手段和机制。事实上,现在有些Unix系统中的管道机制也反过来改成通过socket来实现。

上例的这些进程间通信机制都由linux兼容并蓄继承了下来。事实上这些机制大都是在可移植操作系统接口标准POSIX中规定要具备的。此外,在Unix发展过程中也出现过一些其他的进程间通信机制,但并没有为linux所采用。我们就不作介绍了。

由于篇幅的原因,我们把进程间通信分层两个系列。本系列主要介绍早期的Unix的通信机制以及system V IPC;下一个系列“基于socket的进程间通信”则集中介绍插口(socket)。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/694762.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号