
2.6 分布式系统的互连和通信技术
进程间通信是一切分布式系统的核心。如果不仔细分析分布式系统中各机器间信息交换的机制,对分布式系统的研究就成了空谈。互连和通信技术是分布式系统的基础。低层通信对进程通信提供支持。下面重点论述支持进程通信的计算机互连和低层通信技术(消息传递,Message Passing)。
2.6.1 数据通信协议
1.数据通信协议的概念
由于没有共享存储器,分布式系统中的所有通信都是基于(低层)消息交换的。如果进程A要与进程B通信,进程A必须首先在自己的地址空间中生成该消息,再执行一个系统调用,通知操作系统将该消息通过网络发往进程B。虽然这个基本思路听起来很简单,但是做起来并不简单。为了避免混乱,进程A和进程B必须先就传输的所有位所代表的含义达成一致。
需要制定多种这样的协定(Agreement),比如,用多高的电压来表示0(低电平)信号,又用多高的电压来表示1(高电平)信号?消息接收者如何得知哪一位标志消息的结尾?如何检测消息是否丢失或损坏?发现后该怎么办?数值、字符串及其他数据项的长度是多少?表示方式是什么?
在分布式系统中进行数据通信时,各种交换设备的工作状态和交换步骤的控制由一个通信机制管理,而管理它们的操作规程一般称为数据通信协议(规程)。
一个通信协议可以非形式地定义为在进程之间的通信机制的逻辑与过程的规范说明。为了达到在进程之间的通信,交换信件,要构成通信协议的逻辑规范说明,即协议的句法。另外,为了在进程之间传送、接收和响应信件,又规定各种规则形成了该协议的过程规范说明,即协议的“语义”。
通信协议一般规定如下内容:
(1)帧、分组、报文的格式。
(2)差错控制,如奇偶校验、循环冗余码校验。
(3)顺序号或流水号控制。每个传送单元都有一个顺序号。
(4)代码使用的约束。在用户数据中可能使用控制字符。
(5)线路控制。在半双工、全双工和多点线路方式中决定由哪一个节点发和收。
(6)规定各终端的空闲状态和同步方式。
(7)超时控制和处理。规定时限,超过时限为失败,需要重发。
(8)启动控制。
(9)结束控制。
(10)安全和保密措施。
2.开放系统互连参考模型
国际标准化组织(International Standard Orgnization,ISO)提出开放系统互连(Open System Interconnection,OSI)参考模型,其目的是:
(1)为合作开放系统互连标准提供一个公共基础。
(2)允许将现存的标准放在整个参考模型进行对照。
(3)标志用于开发和改进标准的区域。
(4)为维持所有有关标准的一致性提供一个公共的参数。
ISO的OSI只是为数据交换提供了一种标准协议。采用这种协议可以达到彼此“开放”的目的。整个协议由7层组成,其中高3层面向用户,低4层面向数据传输,如图2-15所示。

图2-15 TCP/IP网与ISO体系结构对照
下面简述7层协议的功能。
(1)物理层(第1层)——Physical Layer,提供机械电气的控制,以便建立维持或拆除设备之间的物理线路。具体的运算服务包括物理的连接器、接口线路的定义、电压、持续时间和数据、控制信号,如RS-232、RS-422/423、IEEE802.3。
(2)数据链路层(第2层)——Data Link Layer,在第1层设施所连接的设备之间提供可靠的数据交换。这一层包括许多服务和运算,如链接初始化、块的帧化、在单个链接中的流控制和错误控制、数据和控制的交换等,如HDLC、SDLC。
(3)网络层(第3层)——Network Layer,是请求网络服务时,在用户和网络之间提供数据与控制的交换。它所包括的服务有在用户和网络之间的流与错误的控制、请求网络服务以及逻辑的多路化、多路转换控制(寻址)、报文发送和路径表、流控制。
(4)传输层(第4层)——Transport Layer,提供一种网络独立接口,以传送假设为可靠服务的串行数据以及控制流。对于按照不同级别和利用传输实体的数据传送服务来提供传输的用户,用户仅由传输地址标志。传输所用重要设施的例子有网络连接、数据报等。
传输服务的内容包括端—端的顺序控制、流控制和回答,端到端的检测、恢复与标记;接通管理、到网络设施的映射和多路化、广播、组地址、服务谈判和性能有效价格服务的选择,分块和帧。该层的标准在Internet上采用的是著名的TCP标准。
(5)会话层(第5层)——Session Layer,支持合作的进程之间的会话和交往。一个会话管理服务用于联编和拆编会议中合作的表示实体,一个会话服务用于控制联编之间的数据交换。会话层的内容包括应用进程选择(Port/Socket机制)、数据交换(常规流、加急流)、变径控制(对话规则)、执程(Transaction)支持、恢复支持(传送中有故障),如ARPA中初始连接控制和操作系统层的流控制约定。
(6)表示层(第6层)—Presentation Layer,该层中主要考虑低层所传输的数据位表示的意义。多数消息并不是由随机的位串组成的,而是由更结构化的信息,如人名、地址、金额等组成。在表示层中,对包含这种结构化信息字段的记录加以定义,随后由发送者通知接收者消息中包含有符合某种特定格式的记录。这种做法使得内部数据表示方法不同的机器间得通信更加方便。
表示层的服务包括高层语言输入或输出的数据结构的解释、虚拟终端变换(如擦除、显示文件)、虚拟存储变换(如文件开始、下一个记录)、加密或解密,如ARPA网络中的文件传输协议(FTP)。
(7)应用层(第7层)——Application Layer,执行应用程序和管理进程间通信。层内的合作应用实体通过应用协议使用低层服务进行相互通信。
应用层的标准例子有系统协议包括远程作业进入与文件传送、应用协议包括文件传送和电子邮件。
上述ISO的OSI 7层协议参考模型,从国际标准化角度看是非常重要的。通常,人们设计和实现协议都是参考7 层协议,但也有一定问题。目前,还没有一个网络和系统完全实现了OSI模式,还未定义出每一层的所有协议,层间的接口也缺乏指导,模式的“完备性”没有充分证明。
3.中间件协议
OSI的应用层起初是准备用来容纳一组标准网络应用程序的,如那些供电子邮件、文件传输以及终端仿真使用的应用程序。但是,应用层现在变成了所有由于各种原因不适于归纳到某个较低层的应用程序和协议的大杂烩。从OSI参考模型的角度来看,几乎所有的分布式系统都只不过是应用程序而已。
这个模型中缺乏对应用程序、针对特定应用程序的协议以及通用协议的准确区分。例如,Internet的文件传输协议(File Transfer Protocol,FTP)规定了一种用于在客户机和服务器间传输文件的协议。该协议不应与FTP程序相混淆,FTP程序是指一种供最终用户使用的应用程序,用来传输文件,而且这种程序恰好(当然不完全是偶然的巧合)实现了Internet FTP协议。
另一个关于针对特定应用程序的协议的例子是超文本传输协议(Hypertext Transfer Protocol,HTTP),它是设计用来对Web页进行远程管理和传输操作的。该协议由Web浏览器以及Web服务器这样的应用程序实现。然而,HTTP目前也用在与Web没有直接联系的系统中。例如,Java的RMI就使用HTTP来向受防火墙保护的远程对象发出调用请求。
还有为数不少的对多数应用程序十分有用的通用协议,但是这些协议并不能算是传输协议。在许多情况下,这种协议只能归入中间件协议的范畴。
中间件是一种应用程序,它在逻辑上位于应用层,它包含多种通用协议,这些协议代表各自所在的层,独立于其他更加特别的应用。可以在高层通信协议和用于建立各种中间件服务的协议间作出区分。
多种协议可以对各种中间件服务提供支持。比如,有很多方法可以进行身份验证(Authentication)——为声称的身份提供证明。身份验证协议与任何特定的应用程序都没有紧密的联系,但是可以作为一种通用服务集成到中间件系统中。同样,授权协议(这种协议允许通过验证的用户和进程对其拥有授权的资源进行访问)在本质上也可以是通用的、独立于应用程序的。
分布式提交协议可作为另一个例子。提交协议确定了在一组进程中,某种操作要么由全体进程共同完成,要么不执行。这种现象也称为原子性(Atomicity),在事务中广泛应用。就像下面介绍的那样,除了事务以外,其他应用程序(如具有容错性的应用程序)也可以利用分布式提交协议。
最后一个例子是关于分布式锁定协议的。这种协议可以保护资源免受分布于多台机器上的一组进程的并发访问。同样,该协议也可以用于实现通用中间件服务,但它又是高度独立于任何特定应用程序的。
中间件通信协议支持高层通信服务。例如,在下面将要讨论允许进程以高度透明的方式调用远程机器上的过程或调用远程机器上的对象的协议。同样,也有用于对实时数据传输进行设定并使其保持同步的协议,这种实时数据传输是多媒体之类的应用程序所需要的。另外,某些中间件系统还提供可靠的多播服务,这种服务的规模可以达到遍及广域网上数以千计的接收者的水平。
某些中间件通信协议也可以归入传输层中,而把它们归入更高层还有一些特殊的原因。比如,可扩展性得到保证的可靠的多播服务只在考虑应用程序需求的情况下才能实现。因而中间件系统可以提供不同的(可调整的)协议,每种协议通过不同的传输协议依次实现,但是各协议提供的接口可以是单一的。
采用这种方案进行分层将形成一种改进的网络通信参考模型,如图2-16所示。与OSI模型相比,会话层和表示层由一个单一的中间件层代替(注意:中间件层实现的功能并不是原会话层和表示层的功能合并,更多的是应用层的功能)。该层包含独立于应用程序的协议,这些协议不属于前述的低层。原来的传送服务可以作为中间件服务来提供,而无需加以改动。这种方案与在传输层提供的UDP有异曲同工之处。同样,在中间件通信服务中可以加入消息传递服务,它与由传输层提供的服务相似。

图2-16 改进的网络通信参考模型
本书将依据这个通信模型研究分布式多媒体计算机系统的通信问题,如中间件通信服务:远程过程调用、远程对象调用、消息队列服务以及通过流为连续媒体通信提供的支持。
2.6.2 低层通信对进程通信的支持
1.低层通信的风范(Paradigm)
随着计算机硬件的价格不断下降、硬件的性能改善,构造分布式计算机系统,引起了人们的关注。进入20世纪90年代以来,大量的研究已建成各种分布式计算机模型系统,人们认为分布式系统是计算机系统发展的必然趋势,问题是如何实现商品化的应用系统。
低层通信是系统的基础,计算机网络和通信已应用了若干年,网络中提供的各种服务都基于虚拟电路模型。虚拟电路是包交换中的一种电路,包含从网络源点到目的节点间的一条通路,所有信息包在呼叫期间不分别编址,通过这个虚拟电路传送并按发送次序相继送到目的地。发送前,首先建立逻辑链路,在逻辑链路上传送信息包。某些逻辑信息不包括数据,只是为了进行控制和管理,传送完即拆除这条链路。这种通信的服务模型,易于理解,便于在网络上使用。
随着分布式系统的发展,这种通信的模型已经改变,其典型的通信的风范是消息传递(Message Passing)。一个消息是从一个进程发送到另一个进程的数据块,系统中的消息可大小固定或大小有些变化,但消息不适合一个网络中的包。
在分布式系统中,基于消息传递和网络中虚拟电路的基本不同涉及到在操作系统中的缓冲区的管理。当使用虚拟电路时,打包和拆包需要复杂的缓冲区管理机制,这是因为从虚拟电路上读或写包可能会出现跨越包的边界问题。当使用消息传递时,缓冲区管理更简单,因为包所包含的数据是一个消息。随着网络速度越来越快,网络的协议开销成为决定传送效率的重要因素。
消息传送通常是嵌入到协议中,为了实现远程操作,一个进程将一个请求发送到另一个进程,这个请求被执行,然后返回一个结果。协议的执行模型是请求/回答协议,也称为客户机/服务器模型,有时也用远程过程调用来实现(RPC)。
请求/回答协议也用来扩展远程过程调用。在这种机制中,两个进程在不同的机器上,参数被组装成一个消息再发送到远地服务器,在服务器上再拆包,推入堆栈。结果返回到请求端采用类似的方法。
这种基于消息传递的通信机制,一般采用数据报的通信服务。数据报是发送方对每个发送的分组给出发送方的全程网络地址。根据全局地址,算法选择路径,传送报文的分组。
2.高速通信的必要性
在分布式系统中,高速通信是关键的部件之一。由于分布式系统的低层采用了高速通信,可以快速地交换大量数据,满足传统的文件存取的需求。低速通信会导致整个系统的性能降低,甚至会限制其他技术的发挥。这非常类似于在20世纪60年代由于高成本且慢速的存储量而限制了操作系统性能的例子。
高速通信可使系统存取文件而不必考虑文件存在的位置,使分布式网络透明性变得可行。由于在分布式系统的低层采用了高速网络,不仅使数据的传播速度加快,而且可以使系统大大地简化,从而不需要进行高度优化。
总之,高速网络技术必将推动分布式系统的发展。
3.轻型通信协议
随着通信技术的发展,网络速度越来越快,通信协议的开销成为传输机制的效率的决定因素。因此,要求人们研究和开发传送的协议、I/O的命名、原子事务、远程执行、迁移和同步等问题。新的挑战是设计高速轻型的协议(Light Weight),以改善性能、功能、可靠性和安全问题。这些问题(如标准化和开放系统的互连)在通信领域受到重视,但在分布式操作系统的设计和分布式系统的实现中未受到足够重视。进入20世纪90年代以来,通信协议向高速轻型发展。所谓轻型协议是指缩短无用的差错数据传送、接收指令的路径长度,减少通信的开销即减少分组交换的次数;调整流控算法,避免缓冲区溢出。
(1)美国Stanford大学在开发分布式系统V-Kernel时采用VMTP(Versatile Message Transaction Protocol),它支持实时事务处理。基于数据报的通信服务,采用了MCB报文控制块+数据块的格式。
(2)美国麻省理工学院(MIT)开发的NETBLT协议(Network Block Transfer)采用大批量数据传输的高性能传输协议,可在任何提供数据报服务的网上运行。它是以“缓存区”发送分组,成批分组送往接收方,利用了Resend、OK、GO等原语。
(3)Delta-T协议是美国Levermore国家实验室开发的轻型协议,采用计时和管理。当发送报文开始时就立即启动计时器,同时送到接收方;当接收方建立连接以后,立即开始计时,采用计时、超时、发送释放进行管理。
(4)XTP协议是美国Protocol Engineering Inc.为高速通信而专门开发的轻型协议。它支持Gb/s光纤高速传送,支持实时功能,采用数据报服务。
2.6.3 消息传递
在集中式单机系统中,进程的同步、互斥及进程之间的通信都是基于共享变量的进程通信机制,而分布式系统中运行的是分布式操作系统,进程之间的通信,由于没有公共存储器,因此基于共享变量的一切进程通信的机制都不适合分布式操作系统的进程通信。
分布式操作系统的特点是,运行在多台通过网络互连的计算机上。系统由于没有公共存储器,因此进程之间的通信是通过不同机器之间进行的,一般采用消息传递(Message Passing)的通信机制。系统的资源分散在各个不同的地点,因而进程调度、资源分配、系统管理等都必须满足分布处理的要求。由于分布式系统自治性的特点,各个处理器既能自主管理局部的(本地的)各种资源,又能接受和处理其他异地(远程)的资源请求,而且尽量达到各地资源负载均衡。为了实现分布式操作系统的上述功能,协同地工作来完成一个任务,进程通信是最关键的问题。
著名计算机科学家Dr. Brinch Hansen(1970年)最先提出消息传递的概念和机制。在分布式系统中利用消息传递进行进程同步和通信时,采用通信原语Send和Receive,取代了在基于共享变量的进程通信中的“读”和“写”。当接收者接收到一个消息时,就获得来自某个发送者进程送来的消息,从而完成了一个进程通信的全过程。一个消息可以被接收者所接收仅当该消息从发送者发出之后才有可能,这显然制约了这两个事件发生的次序,从而实现了同步。一般执行如下操作可以实现发送一个消息。
Send Expression-List to Destination-Identifier
指定者在执行Send原语时,把这个包含了Expression-List给出的表达式的值,送到由Destination-identifier规定的接收端。
在接收端执行如下操作可接收一个消息:
Receive Variable-List from Source-Identifier
其中,Variable-List是一个变量表列,是送来的消息,而Source-Identifier规定了发送者或发送处,即指明了消息来自何处。接收一个消息通常引起两个动作:将消息中的“内容”赋给Variable-List中的变量,接着把这条消息毁掉。
通常,设计分布式操作系统时很重要的内容是规定通信原语。设计通信原语必须考虑两个问题:一是如何发送和规定接收者,二是规定消息和如何通信、同步。
1.消息(Message)
一个消息可以看成是一类数据对象的汇集,它靠进程来构造,它被进程管理且交付到最后的通信目的进程。一般一个消息具有大小固定的消息头和变长的实体,整个消息靠进程来管理和提交到它的目的进程。一个消息可以是任意大小,可以包括数据或各类指针。消息的内容由发送进程来确定。另外,有些消息头部分由系统的相关的信息所决定。
图2-17给出两个简单的消息格式。
图2-17(a)是简单的消息头的数据格式,图2-17(b)是具有指针的消息格式。最重要的问题是如何构造一个消息。理想的消息应包括程序对象,利用这种结构,进程之间的通信是从一个进程的地址空间传到另一个进程的地址空间。消息的实现可以结构化或非结构化。如果使用非结构化消息,则需要靠用户进程来解释有关问题。因为消息的有些部分(如源端口名字)必须靠分布式操作系统的内核来解释,需要解释成另一台机器上的相应的进程可接受的意义。在异构型分布式系统网络中,只有某些类型的信息(如整数、实数和字符串)可以在系统中透明传输。结构化的消息从效率角度来看也是人们所青睐的。因此,大多数在进程间传递的消息都是结构化的。采用非结构化消息的开销大,在系统中增加一层使通信的开销增大。

图2-17 消息格式
2.通信原语(Primitive)
1)基本原语
消息传递的进程通信机制的工作原理非常类似于上述基于客户机/服务器的模型。一个进程或一个客户机(发送者)将消息(即请求)发送到另一个进程,然后服务器或接收者返回一个回答消息给客户或发送方。这种通信机制的最重要问题是确定那些通信原语和它们的语义。
下面给出典型的通信原语:
Send Expression-list to Destination-Identifier
执行时,在Expression-List中包括的表达式的值即消息。用户和进程发送的目的地址用Destination-Identifier决定,它可以是一个目的或多个目的节点广播地址。
Receive Variable-List from Sourc-Identifier
Variable-list是一个变量表,接收从源id发来的消息。
最简单的通信原语是上述的Send和Receive。在通信过程中参与的两个进程,如图2-18所示。

图2-18 用Send和Receive原语在客户机/服务器之间通信
Client Process:
Send(Server,message)
Server Process:
Receive(Process-id,buffer)
如上所述,在客户进程规定要发送的目的地址(即服务器)和构造要发送的消息;而服务器进程提供一个缓冲区以存放要发来的消息。相反,如果服务器发送消息给客户进程,同样要使用Send发送原语,而客户要用Receive原语来接收消息。
有时,利用选择接收原语从一系列的消息来源中选择一个准备好的消息。一系列的选择接收原语表示如下:
Select
Receive Variable-List from Source-id1
or Receive Variable-List from Source-id2
or Receive Variable-List from Source-id3
end
这种选择接收原语用于在某些情况下,消息超过一个来源,接收通常是非决定性的,如上所述可以从三个来源接收消息。
这里所要讨论的问题都与原语中包含什么语义有关,Liskov曾提出如下的通信原语:
the No-Wait Send
该通信原语是当消息组成后就发送。
the Synchronization-Send
该通信原语只要接收到目的进程发来的要求通信的信号,就开始同步交换消息。
the Remote Invocation Send
发送进程等待,直到从接收进程收到一个回答信号,说明该命令已经执行。
通信原语按其功能又可分为:
(1)封锁和非封锁原语。
(2)缓冲和非缓冲原语。
(3)可靠和不可靠原语。
(4)大小固定或变长消息数据原语。
(5)直接或间接通信端口。
(6)传送值参数或指针参数。
2)封锁与非封锁原语
在基于消息传递的通信原语中,其最重要的特点和性质是,在执行过程中能否引起延迟。封锁和非封锁原语是完全不同的。一个原语具有非封锁的语义是指在执行过程中从不延迟,否则就是一个封锁原语。在前者情况下,消息必须被缓存。
(1)非封锁原语:该原语是指在发送一个消息时,其本身在发送消息的同时还可以执行。当一个消息被传送时,通知这个缓冲区可以重用。对应的Receive原语发送一个愿意接收信号,接收消息并提供一个缓冲区来存放发来的消息,靠中断来通知接收程序已收到。
这种非封锁原语的优点是,它们提供最大的灵活性;最主要的是,这类原语对实时应用特别有用。例如,一个进程用来控制一个温度,因本身是动态,而不是等收到一个回答信号再继续接收下一个温度控制信号。缺点是,当回答信号被接收或为了防止在存取过程中消息被改变,在源节点和目的节点都必须设置缓冲区。如果一个缓冲区满了,进程必须被封锁。这与原语原来的定义矛盾。
(2)封锁原语:封锁原语提供一种简单方法来组合数据传送和同步功能。如果这个Send原语是封锁的语义,则直到这个接收进程实际上接收这个发送来的消息,这个发送者一直被封锁。另外,这个接收端也被挂起,直到这个发送进程执行完发送请求。在整个过程中,发送和接收是一个同步的过程。
这种封锁原语中的封锁直到消息发送完,才将控制返回到用户,程序可以修改缓冲区。对可靠的封锁,直到发送完消息和收到一个回答信号才将控制返回到用户,程序可以修改缓冲区。接收进程直到消息被放在缓冲区才返回控制。封锁和非封锁通信原语不冲突。
有三种类型的接收原语。封锁接收是最普通的,因为接收进程在期待接收一个消息时,通常不做任何事。也有一些不封锁的接收进程,用于检查一个消息是否可利用,从而使一个进程可以接到所有的消息和将一个选择到这个进程中。发送和接收通信原语具有封锁语义如图2-19所示。

图2-19 具有封锁语义的发送和接收通信原语
问题是,封锁原语禁止它们并行工作,一个进程在发送和接收时被封锁,无法工作。
3)缓冲与非缓冲通信原语
有些通信原语在发送和接收时,消息被缓冲。在发送(Send)时,如果缓冲区满了,会发生两种结果。一种是发送(Send)延迟,直到在缓冲区有一个空间可存放一个消息;另一种是给发送者返回一个编码信号,表示缓冲区已满,不能再发送消息。接收(Receive)时也会出现类似上述情况。
分析考虑上述结果有两个极端的情况:一是有无限缓冲区,二是无缓冲区。前者无限大时执行Send,则无延迟。基于上述情况的系统是异步消息传送或消息具有不等待的发送。这种异步消息传送的最大特点是,它允许一个发送者有一个任意大的接收者。当一个消息被接收时,它包括的发送者的状态信息不再有效。如果一个系统没有缓冲区,则发送执行总是被延迟,直到对应的接收执行完为止。然后,消息被传回,发送和接收继续进行。如果缓冲是有限的世界,则消息传递是缓冲的信息。在这种情况下,缓冲的消息传递的系统如下。
(1)一个发送者在基于缓冲机制上可以有多个Send发送。
(2)最常用的方法是,为用户提供一个系统调用Create Buffer,来创建一个内核缓冲区,有时称为Mailbox(信箱)或Port(端口),其大小由用户自己决定。
(3)这种方法意味着,发送者将一个消息发送到接收端口,消息被缓冲,直到接收者要求这个消息。
具有缓冲的消息传递的特点是:
(1)它比不缓冲的消息传递更复杂,因为它要求创建、毁坏和管理缓冲区。
(2)它会产生一个保护机制问题。
(3)当一个进程拥有的端口死了或被杀死时,会发生系统灾难性的问题。
在系统中使用非缓冲策略,为了确保消息传送到指定的地点,进程必须被同步。这种同步称为约会(Rendezvous),分为本地约会和远程约会。因为这种策略很重要,下面加以讨论。
(1)本地约会(Local Rendezvous):为了在同一程序中的同一地址空间,两个进程进行双向通信,采用这种本地约会的机制。
进程在入口可以有输入和输出两种参数。当约会开始时,输入参数从发送或调用者传送到接收或被调用的进程,输出参数是由接收者在约会结束时传回到发送者,如图2-20所示。当本地约会时,事件发生的顺序如下。

图2-20 约会事件的顺序
① 如果发出接收在发送约会之前,则接收被挂起。当约会调用发生时,输入参数从发送者复制到接收者,则发送被挂起,接收者执行输入过程码。当输入过程完成时,执行输出参数从接收者复制到发送者,使约会调用恢复执行。
② 如果发送调用发生在接收被约会之前,发送者被挂起。
(2)远程约会:远程约会是本地约会的一个扩充。远程约会的语义,尽管可能很远但与本地约会的语义完全相同。
远程约会被调用严格地与本地约会完全相同,参数传送和包交换在计算机网络上完全一样。图2-21示出远程约会的协议。

图2-21 远程约会的协议
发送者执行调用,发送输入参数。接收者收到参数后,首先发出回答信号,然后发出返回输出参数。发送者收到输出参数后,再向接收者发出回答消息,完成远程约会的过程。
4)不可靠与可靠的通信原语
系统可靠性是相对的,不可靠是绝对的。在系统中,各种不同的灾难事件发生,如节点坏或局域网中的通信系统故障,都可能引起一系列的不可靠问题而造成以下情况。
(1)一系列的数据在网络上丢失。
(2)一个回答消息丢失或延迟。
(3)对应节点将结束或变成不可靠。
这样会引起以下的不可靠问题。
(1)不可靠的通信原语(如图2-22所示):这种不可靠的通信原语只能通过Send把消息送上网络,不能确保交付到目的节点,当消息丢失时也不能自动重传。

图2-22 不可靠的通信原语
(2)可靠的通信原语(如图2-23所示):由于通信过程可能出现各种故障,因此要求提供可靠的通信原语进行进程通信。

图2-23 可靠的通信原语
如果Send原语丢失了消息,可以在内部重传或基于超时而发一个回答。这意味着当Send结束时,就确保收到发送的消息并给出回答。
在很多情况下,一个请求多次重复执行可能导致破坏了一致性。下面给出两种类型的语义和恢复机制:图2-24所示是最少一次恢复机制,图2-25所示是严格一次恢复机制。

图2-24 最少一次恢复机制

图2-25 严格一次恢复机制
3.基于链路(Link)和端口(Port)的进程通信
消息传递的下一个问题是消息传到哪里和如何传送。消息在进程间的通信采用两种技术之一,即发送者规定了一个目的进程或接收消息的固定地址。前者为直接通信,而后者为间接通信。
1)对称寻址方式
Send(P,message)
将一个消息发送到进程P。
Receive(Q,message)
从进程Q接收一个消息。
在这种方案中,一个通信链路(Link)有如下特征:
(1)进程之间要通信,利用一个Link自动地建立,进程只需要知道互相通信的本身。
(2)一个Link最终与两个进程有关。
(3)一对通信的进程最终只有一个Link。
(4)Link是双向的。
2)不对称间接寻址方式
这种不对称寻址的消息传递,只是发送者命名一个接收进程。相反,接收者不要求命名发送者。Send和Receive原语如下。
Send(P,message)
将一个消息发送到进程P。
Receive(id,message)
从任一个进程接收消息(id是要通信的进程名字的id号码)。
3)Link(链路)
一个Link被定义为一个用户进程、系统进程或内核进行通信的通道。用Link作为一个通信工具时,每一个进程有一个与它相关的Link表。一个进程可以建立和破坏一个Link。发送者必须有一个Link,而接收者响应这个Link。
Link能有效地支持进程迁移,另外也可以应用双向Link。
面向Link的通信原语如下。
Send(Link,Buffer)
发送一个消息,从缓冲区Buffer出发沿着规定的Link发送消息。
Receive(Link,Buffer)
在规定的Link接收一个消息,并把消息放在Buffer(缓冲区)中。
Send(Link,Buffer,Link-end)
Send原语允许沿着规定的Link发送一个Link-end,把Link-end送到规定传送的Link上,并把它放在Buffer缓冲区中。
4)端口(Port)
(1)信道通信:在分布式操作系统中,两个进程之间的通信可以采用信道方式。一个信道有两个端口,它分别被两个进程持有。持有信道端口的进程可以通过该信道将信件发给持有另一个端口的进程,或接收从它那里发来的信件。一个信道的两个端口在它所属的两个进程中分别有一个标号。
如图2-26(a)所示,进程A和进程B之间的信道在进程A的端口标号为端口21,而在进程B的端口标号为端口20。进程A可沿这条信道的端口21给进程B发信件,或接收由进程B发来的信件。同样,进程B则沿着信道端口20可以与进程A通信。这种信道寻址方式就是采用端口标号来指出信件沿哪个信道发送,从而将信件送至相应的进程;或者指出从哪个信道接收信件。
(2)端口的转让:当一个进程与另一个进程通信完毕后,可以把它持有的信道端口转让给另一个进程,使另外两个进程建立起通信关系。如图2-26(b)所示,当进程B将它持有的一个与进程C相连的信道端口通过信件转让给另一个进程A后,使进程A和进程C建立起信道便可进行进程通信。具体做法是,进程B可以将它的信道端口21附在信件中通过端口20送给进程A,进程A获得进程B发来的信道端口之后,将它编号为端口11,它便可以通过端口11与进程C通信。特别是当一个进程将该进程所持有某信道的两个端口分别传递给两个进程,就给另外两个进程建立了通信关系。

图2-26 信道寻址方式和端口传送

图2-27 通过传送端口建立通信关系
(3)端口的创建:如图2-27(a)所示,进程C利用系统创建信道原语获得一个信道的两个端口。然后,它把这两个端口分别传递给进程A和B,成为它们的信道端口22和端口21。此后,进程A和进程B就可以通过信道端口22和端口21进行通信,如图2-27(b)所示。
(4)优点:用信道指出通信目标的方式具有许多优点。
① 操作系统只要为本机上那些进程建立的信道保存一张进程地址表。例如,进程X与它机上的进程Y建立了信道L后,操作系统将记住进程X的信道L是指向某机上的进程Y的,也就是说,只需保存一张信道端口标号与目标地址的对照表。对于一个包含很多进程的大系统,信道数远低于进程总数,因此,分布式操作系统为通信寻址所需保留的信息量比按名寻址要少得多。
② 一个进程只能同与它建立了信道的进程通信,这对系统的安全性大有好处。
③ 信道的一个端口的持有者可以完全不考虑信道另一端持有者的改变。
因此,一个进程通过一个信道可以不同时地与多个进程通信。这种端口的性能对设计分布式操作系统的实用程序(Utility)是很有用的。例如,实用程序进程U持有信道L的一个端口,L的另一个端口为资源管理R所持有。R将此端口传给谁,谁就可与U通信并调用它;未获得L的端口者不能调用U。这就很方便地实现了资源的互斥调用。
(5)基于端口的通信原语:利用上述端口构成的通信原语如下。
接收原语:
Receive(B,message)
接收从端口B发来的一个消息。
这种方式通信有如下特点:
(1)它可以与两个以上的进程建立通信关系。
(2)可有许多不同的通道在两个进程之间建立通信关系。每个进程对应一个端口。
(3)基于端口可以单向,也可双向。
发送原语:
Send(A,port)
一个port的所有者能把一个port放入消息中从一个进程送到另一个进程。接收到一个端口也可以再传送。在分布式操作系统中,port的所有者可以:
(1)创造新端口。
(2)通过端口发送和接收消息。
(3)破坏一个端口。
不难看出,进程通信是分布式操作系统提供的一项基本功能,而通信原语是提供进程通信、交换数据的重要工具。这些原语是按照通信协议所规定的规则来实现的。因此,在实现通信原语之前,必须先设计和实现通信协议的较低的三层。这些通信原语就构成了系统的通信机制,也可称为通信机制的低级部分。
通信原语不仅支持进程间通信,而且还支持各种分布式程序设计语言的通信功能。设计分布式操作系统的通信原语应具有如下功能。
(1)独立性:通信机制与网络拓扑结构无关,它允许系统动态重新组合。
(2)有效性:通信机制使通信开销尽可能小,以保证系统有效性。
(3)简单性:通信机制应尽量简单、方便、易于实现和使用。
(4)保护性:通信机制应有保护措施。