进程间通信管道
普通的Linux shell都允许重定向,而重定向使用的就是管道。例如:
$ ls | pr | lpr
把命令ls(列出目录中的文件)的输出通过管道连接到命令pr的标准输入上进行分页。最后,命令pr的标准输出通过管道连接到命令lpr的标准输入上,从而在缺省打印机上打印出结果。进程感觉不到这种重定向,它们和平常一样地工作。正是shell建立了进程之间的临时管道。
管道是单向的、先进先出的、无结构的、固定大小的字节流,它把一个进程的标准输出和另一个进程的标准输入连接在一起。写进程在管道的尾端写入数据,读进程在管道的首端读出数据。数据读出后将从管道中移走,其它读进程都不能再读到这些数据。管道提供了简单的流控制机制。进程试图读空管道时,在有数据写入管道前,进程将一直阻塞。同样,管道已经满时,进程再试图写管道,在其它进程从管道中移走数据之前,写进程将一直阻塞。
传统上有很多种实现管道的方法,如利用文件系统、利用套接字(sockets)、利用流等。在Linux中,使用两个file数据结构来实现管道。这两个file数据结构中的f_inode(f_dentry)指针指向同一个临时创建的VFS I节点,而该VFS I节点本身又指向内存中的一个物理页,如图5.1所示。两个file数据结构中的f_op指针指向不同的文件操作例程向量表:一个用于向管道中写,另一个用于从管道中读。这种实现方法掩盖了底层实现的差异,从进程的角度来看,读写管道的系统调用和读写普通文件的普通系统调用没什么不同。当写进程向管道中写时,字节被拷贝到了共享数据页,当读进程从管道中读时,字节被从共享页中拷贝出来。Linux必须同步对于管道的存取,必须保证管道的写和读步调一致。Linux使用锁、等待队列和信号(locks,wait queues and signals)来实现同步。
右图 --管道示意图所示
参见include/linux/inode_fs.h
当写进程向管道写的时候,它使用标准的write库函数。这些库函数(read、write等)要求传递一个文件描述符作为参数。文件描述符是该文件对应的file数据结构在进程的file数据结构数组中的索引,每一个都表示一个打开的文件,在这种情况下,是打开的管道。Linux系统调用使用描述这个管道的file数据结构中f_op所指的write例程,该write例程使用表示管道的VFS I 节点中存放的信息,来管理写请求。如果共享数据页中有足够的空间能把所有的字节都写到管道中,而且管道没有被读进程锁定,则Linux就在管道上为写进程加锁,并把字节从进程的地址空间拷贝到共享数据页。如果管道被读进程锁定或者共享数据页中没有足够的空间,则当前进程被迫睡眠,它被挂在管道I节点的等待队列中等待,而后调用调度程序,让另外一个进程运行。睡眠的写进程是可以中断的(interruptible),所以它可以接收信号。当管道中有了足够的空间可以写数据,或者当锁定解除时,写进程就会被读进程唤醒。当数据写完之后,管道的VFS I 节点上的锁定解除,在管道I节点的等待队列中等待的所有读进程都会被唤醒。
参见fs/pipe.c pipe_write()
从管道中读取数据和写数据非常相似。Linux允许进程无阻塞地读文件或管道(依赖于它们打开文件或者管道的模式),这时,如果没有数据可读或者管道被锁定,系统调用会返回一个错误。这意味着进程会继续运行。另一种方式是阻塞读,即进程在管道I节点的等待队列中等待,直到写进程完成。
如果所有的进程都完成了它们的管道操作,则管道的I节点和相应的共享数据页会被废弃。
参见fs/pipe.c pipe_read()
Linux也支持命名管道(也叫FIFO,因为管道工作在先入先出的原则下,第一个写入管道的数据也是第一个被读出的数据)。与管道不同,FIFO不是临时的对象,它们是文件系统中真正的实体,可以用mkfifo命令创建。只要有合适的访问权限,进程就可以使用FIFO。FIFO的打开方式和管道稍微不同。一个管道(它的两个file数据结构、VFS I节点和共享数据页)是一次性创建的,而FIFO已经存在,可以由它的用户打开和关闭。Linux必须处理在写进程打开FIFO之前读进程对它的打开,也必须处理在写进程写数据之前读进程对管道的读。除此以外,FIFO几乎和管道的处理完全一样,而且它们使用一样的数据结构和操作。
从IPC的角度看,管道提供了从一个进程向另一个进程传输数据的有效方法。但是,管道有一些固有的局限性:
l 因为读数据的同时也将数据从管道移去,因此,管道不能用来对多个接收者广播数据。
l 管道中的数据被当作字节流,因此无法识别信息的边界。
l 如果一个管道有多个读进程,那么写进程不能发送数据到指定的读进程。同样,如果有多个写进程,那么没有办法判断是它们中那一个发送的数据。
1. 施工内容: 1) 器材检验: ① 通信管道工程所用的器材规格、程式及质量,应满足 设计文件和技术规范的要求,并由施工单位会同建设 单位或监理单位在使用之前组织进场检验,发现问题 或不合格的器材应及时处理。 ② 通信管道工程中使用水泥的品种、标号应符合设计要 求。各种标号的水泥应符合国家规定的产品质量标准。 ③ 通信管道工程宜使用天然中砂,平均粒径为 0.35~ 0.5mm。通信管道用砂技术指标应符合国家标准 《建筑 用砂》。 ④ 通信管道用砖技术指标应符合国家标准。石子应采用 人工碎石或天然砾石,不得使用风化石。 ⑤ 人(手)孔井盖装置 (包括外盖、内盖、口圈等 )的规格 应符合标准图的规定。 2) 工程测量: 通信管道工程的测量,应按照设计文件及城市规划部门 已批准的位置、坐标和高程进行。施工前,必须依据设计图 纸和现场交底的控制桩点, 进行通信管道及人 (手)孔位置的 复测。 3
COM是微软自1993年便提出的组件式软件平台,用来做进程间通信(Inter-process communication, IPC)以及当作组件式软件开发的平台。COM提供跟编程语言无关的方法实现一个软件对象,因此可以在其他环境中运行。COM要求软件组件必须遵照一个共同的接口,该接口与实现无关,因此可以隐藏实现属性,并且被其他对象在不知道其内部实现的情形下正确的使用。
COM并被实现于多个平台之上,并不限于Windows操作系统之上。但还是只有Windows最常使用COM,且某些功能已被目前的.NET平台取代。
《建筑智能化系统及工程应用》中介绍了Windows NT网络操作系统的原理及应用,重点讨论了Windows NT网络协议、网络边界层、进程间通信机制,及对Win32/Win16和MS"_blank" href="/item/电气信息类/5294336" data-lemmaid="5294336">电气信息类、仪器仪表以及机电类各专业本科教学使用,也可供相关工程技术人员参考。
《建筑智能化系统及工程应用》是近些年来编者从事智能建筑教学实践、科研及实际智能建筑工程项目的经验总结。考虑各院校专业基础课安排侧重点及体系结构的差异,以及教学侧重点不同,课堂的理论教学学时少,教学内容多,又要加强工程实践环节的需要,因此,在教材处理上,各章节安排相对独立,但又注意相对完整性、系统性,使之通俗易懂便于自学,给实施课堂教学的主讲老师以更多的灵活性,不讲授部分可以指定学生自学或供学生参考阅读。《建筑智能化系统及工程应用》第1~9章为基本内容,第10章是一个实际工程项目的设计范例,较完整地讨论了一个中央集成管理系统,有一定可操作性,可供学生参考。2100433B
管道是Linux/UNIX系统中比较原始的进程间通信形式,它实现数据以一种数据流的方式,在多进程间流动。在系统中其相当于文件系统上的一个文件,来缓存所要传输的数据。管道通信是最常见的通信方式之一,其是在两个进程之间实现一个数据流通的管道,该管道可以是双向或单向的。
我们将仅能在一个方向上传递信息的管道称为半双工管道,将可在两个方向上传递信息的管道称为全双工管道。管道是一种很经典的进程之间的通信方式,其优点在于简单易用,其缺点在于功能简单,有很多限制。