操作系统原理学习笔记(九)-进程通信

操作系统原理学习笔记目录

进程通信

进程通信:
进程之间的信息交换。

低级进程通信:
如信号量机制,在互斥与同步时,需要交换信息,
效率低:每次只能交换一个消息。
通信对用户不透明:OS只为进程通信提供共享存储器,进程通信的设计、存储、传输都需要程序员去实现。

OS提供的高级通信工具特点:
使用方便:隐藏通信时细节,提供一组用于实现高级通信的原语命令,方便使用。
高效传输大量数据:用户可直接利用高级通信原语高效的传输大量数据。

进程通信的类型

目前,高级通信机制可归结为四大类:
共享存储器系统、管道通信系统、消息传递系统、客户机-服务器系统。

共享存储器系统(Shared-Memory System)
  • 基于共享数据结构的通信方式:要求诸进程共用某些数据结构,以实现进程间信息交换,如生产者-消费者问题中的有界缓冲区。适用于传递少量的数据,通信效率低下,属于低级通信。
  • 基于共享存储区的通信方式:在内存划分一块共享存储区域,进程间信息交互在此由进程完成。使用前,向系统申请,并对其中进行读写操作,完成后退还给系统,属于高级通信。
管道(pipe)通信系统

首创于Unix系统,在Unix系统中,分为有名管道(fifo)与无名管道(pipe)。
管道文件连接一个读进程与一个写进程,以字符流形式传输。
为了协调双方通信,需实现三方面的协调能力:
互斥:读/写操作不允许同时进行。
同步:写进程将一定量数据写入pipe后,睡眠等待,直到读进程取走数据,再将它唤醒。当pipe空时,读进程睡眠等待,知道写进程写入数据后被唤醒。
确定对方存在:双方均存在时才能通信。

消息传递系统(Message passing system):

不借助任何共享存储区或数据结构,而是以格式化的消息(message)为单位,将通信数据封装在消息中,并利用OS提供的一组通信原语进行消息传递。
例如,计算机网络中的报文传递,就是该类消息的一种形式。
直接通信方式:发送进程利用OS提供的发送原语,直接将消息发给目的进程。
间接通信方式:发送与接受进程,都通过共享中间实体(称为邮箱)的方式通信。

客户机-服务器系统(Client-Server system):

在网络环境的各种应用领域中属于主流通信实现机制。
三类实现方法:套接字、远程过程调用、远程方法调用。

套接字(Socket)

(这部分内容太长了,为了排版一致不好分段,我后面可能会从计算机网络的角度再写一篇关于套接字的。)
一个套接字就是一个通信标识类型的数据结构,包含通信目的地址、通信端口号、通信网络传输层协议、进程所在网络地址、针对客户或服务器程序提供的不同系统调用等。
是进程通信和网络通信的基本构件,包括两类:

基于文件型:通信进程处于同一台机器中,一个套接字关联一个特殊文件,通信双方通过该文件实现通信,类似pipe通信。

基于网络型:采用非对称方式通信,即发送者需要提供接受者命名。通信双方的进程运行在不同主机的网络环境下,被分配一对套接字,分属于接受与发送进程。一般地,发送进程发出连接请求时,随机申请一个套接字,并由主机分配一个端口绑定。接受进程拥有全局公认的套接字和指定的端口(如FTP监听21端口,Web或http服务器监听80端口),并通过监听端口等待客户请求。因此,任何进程都可以向其请求,以便通信连接建立。接受进程受到请求后,接受通信请求的连接,完成连接,即在主机间传输的数据可以准确发送到通信进程,实现进程间通信,通信结束时,系统通过关闭接受进程的套接字以撤销连接。

优势:不仅可用于机器内进程通信,还可以用于网络环境中不同计算机间的进程通信。由于套接字标识符唯一,不同的进程通信便于区分,确保通信双方之间逻辑链路的唯一性,便于实现数据传输的并发服务,并隐藏了通信设施及实现细节,采用统一的接口进行处理。

远程过程调用和远程方法调用

远程过程(函数)调用RPC(Remote Procedure Call),是一个通信协议,用于通过网络连接的系统。该协议允许一台主机系统的进程调用另一台主机系统上的进程。如果涉及的软件采用面向对象编程,那么远程过程调用也可称为远程方法调用。
负责远程过程调用的进程有两个,一个本地客户进程,另一个是远程服务器进程,两个进程都被称为网络守护进程,主要负责网络间消息传递,一般情况下,两个进程都处于阻塞状态等待消息。
为了使PRC看上去与本地过程调用一样(实现RPC透明性),RPC引入一个存根(stub)的概念:在本地与服务器各有与过程关联的存根,调用过程,就是调用存根。

远程过程调用的主要步骤:
1.本地过程调用者以一般方式调用远程过程在本地关联的客户存根,传递相应参数,然后将控制权转移给客户存根。
2.客户存根执行,完成包括过程名和调用参数等信息的消息建立,将控制权转移给本地客户进程。
3.本地客户进程完成与服务器的消息传递,将消息发送到远程服务器进程。
4.远程服务器进程接受消息后转入执行,并根据其中的远程过程名找到对应服务器存根,将消息转给该存根。
5.服务器存根接受消息后,由阻塞转执行状态,拆开消息,然后以一般的方式调用服务器上关联的过程。
6.服务器处理完成后,将结果返回给与之关联的服务器存根。
7.服务器存根获得控制权运行,将结果打包成消息,并将控制权转移给远程服务器进程。
8.远程服务器进程将消息发送回客户端。
9.本地客户进程接受消息后,根据其中过程名将消息存入关联的客户存根,再将控制权转移给客户存根。
10.客户存根从消息中取出结果,返回给本地调用者进程,并完成控制权的转移。

消息传递通信的实现方式

进程间可以通过直接或间接的方式通信。

直接消息传递系统

使用OS提供的发送原语发送消息。

直接通信原语:
对称寻址方式:要求发送进程与接收进程以显式方式提供对方标识符,通常,系统提供两条通信原语:
send(receiver, message); //发送消息给接收进程
receive(sender, message); //接收Sender发来的消息

这种方式的不足在于,一旦改变进程名称,需要对所有相关引用进行检查,不能同步更新。
非对称寻址方式:接收方可能需要与多个发送进程通信,无法指定发送进程,对于这样的应用,在接收进程的原语中,不需要命名发送进程,只填写进程参数,即完成通信后的返回值:
send(P, message); //发送一个消息给进程P
receive(id, message); //接收来自任何进程的信息,id变量设置为进行通信的发送方进程id或名字

消息的格式:
对于单机系统环境中,可采用定长消息传递,减少资源开销。
若消息较长,可采用变长消息传递,方便用户,但开销加大。

进程的同步方式:
发送进程阻塞,接收进程阻塞:用于进程之间紧密同步,无缓冲的情况。
发送进程不阻塞,接收进程阻塞:应用最广的同步方式,发送进程可以尽快把多个消息发送给多个目标。
发送进程不阻塞,接收进程不阻塞:较常见,当发生某事件使得进程无法运行时,才把自己阻塞等待。

通信链路:
有两种建立方式。
1.发送进程在通信前用显式的建立连接原语请求系统建立通信链路,使用完后拆除,主要用于计算机网络中。
2.发送进程无需明确提出请求,只需利用系统提供的发送原语即可自动建立一条链路。
有两种通信方式:
1.只允许单向传递消息。
2.允许双向同时传递消息。

信箱通信

信箱通信属于间接通信方式,信箱有唯一标识符。
信箱(邮箱)是一个建立在随机存储器的公用缓冲区上,用来暂存消息的实体。
利用信箱即可实现实时通信,也可实现非实时通信。

信箱的结构:
信箱定义为一种数据结构,在逻辑上,可分为两个部分:
信箱头:存放信箱描述信息,如信箱标识符、信箱拥有者、信箱口令、信箱空格数等。
信箱体:由若干个可存放消息/消息头的信箱格组成,其数目及大小是在创建信箱时确定的。
消息传递可以是单向的,也可以是双向的。

信箱通信原语:
信箱的创建和撤销:进程可通过邮箱名字、邮箱属性创建信箱。对于共享信箱,还需给出共享者名字。进程不需要读信箱时,可用撤销原语撤销。
消息的发送和接受:进程之间使用信箱通信时,必须使用共享信箱,利用下面两个通信原语通信:
Send(mailbox, message); //发送一个消息至指定信箱
Receive(mailbox, message); //从指定信箱中接受一个消息

信箱的类型:
可由OS或用户进程创建,创建者即是拥有者,信箱分为三类:
私用信箱:用户进程为自己创建,并作为进程一部分,只有用户进程可读该信箱,其他用户只能发送消息到该信箱,该进程结束时,信箱随之消失。
公用信箱:由OS创建,提供给系统中所有核准进程使用,核准进程可发送消息至信箱,并读取发送给自己的消息。
共享信箱:由进程创建,创建时或创建后指明它是可共享的,并指出共享进程(用户)的名字。拥有者与共享者都可取走发送给自己的消息。

发送进程与接收进程之间的关系:
一对一关系:发送进程与接收进程建立一条两者专用的通信链路,使得两者信息交互不受其他进程干扰。
多对一关系:允许提供服务的进程与多个用户进程之间进行交互,也成为客户机/服务器交互(client/server interaction)。
一对多关系:允许一个发送进程与多个接收进程进行交互,使得发送进程可用广播方式向(多个)接收者发送消息。
多对多关系:允许建立一个公用信箱,让多个进程能向信箱中投递消息,并可取出发送给自己的消息。

直接消息传递系统实例

这部分在书上79页,全是代码,望而生畏。

You may also like...

发表评论

邮箱地址不会被公开。 必填项已用*标注