进程通信
1、定义:
进程通讯是指进程之间的信息交换。
在进程之间要传送大量数据时,就需要使用进程通讯。
进程互斥和同步需要交换一定的信息,它们也可归为进程通讯,属于低级的进程通讯。低级的原因在于
(1)、效率低,生产者每次只能向缓冲池投放一个产品(消息),消费者每次只能从缓冲池中取得一个消息
(2)、通讯对用户不透明,OS职位进程之间的通讯提供了共享存储其。
2、进程通讯特点:
- 使用方便。OS隐藏了实现进程通讯的具体细节,向用户提供了一组用于实现高级通信的命令(原语),用户可方便的直接利用它实现进程之间的通信,或者说,通信过程对用户是透明的,这样大大减少了通信程序编制上的复杂性。
- 高效的传送大量的数据。用户可以直接利用高级通讯命令(原语)高效地传送大量的数据。
3、进程通信的分类
- 共享存储器系
在该系统中,相互通信的进程共享某些数据结构或共享存储区,进程能通过这些空间进行通信。
- 管道通信系统
- 消息传递系统
- 客户机-服务器系统
3.1、共享存储器系
(1)、基于共享数据结构的通信方式。在这种通信方式中,要求诸进程公用某些数据结构,借以实现诸进程间的信息交换,如在生产者-消费者问题中的有界缓冲区。操作系统仅提供共享存储器,由程序员负责对公共数据结构的设置及对进程间同步的处理。这种通信方式仅适用于传递相对较少的数据,通信效率低下,属于低级通信。
(2)、基于共享存储区的通信方式。为了传输大量数据,在内存中划出了一块共享存储区域,诸进程可通过对该共享区的读或写交换信息,实现通信,数据的形式和位置甚至访问控制都是进程负责,而不是OS。这种通信方式属于高级通信。需要通信的进程在通信前,像系统申请获得共享存储区中的一个分区,并将其附加到自己的地址空间中,便可对其中的数据进行正常读、写,读写完成或不再需要时,将归还给共享存储器。
3.2、管道通信系统
所谓“管道”,是指用于连接一个读进程和一个写进程以实现它们之间通信的一个共享文件,又名pipe文件。
向管道(共享文件)提供输入的发送进程(即写进程)以字符流形式将大量的数据送进管道;而接受管道输出的接受进程(即读进程)则从管道中接收(读)数据。
为了协调双方的通信,管道机智必须提供下面三方面的协调能力
- 互斥,即当一个进程正在对pipe执行读/写操作时,其他(另一)进程必须等待。
- 同步,指当写(输入)进程把一定数量(如4KB)的数据写入pipe,便去睡眠等待,知道读(输出进程)取走数据后再把它唤醒,当读进程读一空pipe时,也应睡眠等待,直到读(输出)进程取走数据后把它唤醒。
- 确定对方是否存在,只有确定了对方已存在时才能进行通信。
3.3、消息传递系统
不借助任何共享存储区或数据结构,而是以格式化的消息(messag)为单位,为通信的数据封装在消息中,并利用操作系统提供的一组通信命令(原语),在进程间进行信息传递,完成进程间的数据交换。
分类:
- 直接通信方式,指发送进程利用OS所提供的发送原语,直接把消息发送给目标进程;
- 间接通信方式,指发送和接受进程,都通过共享中间实体(简称邮箱)的方式进行消息的发送和接受,完成进程间的通信。
3.4、客户-服务器系统
在网络环境的各种应用领域已成为当前主流的通信实现机制,主要的实现方法分三类:套接字、远程过程调用和远程方法调用。
(1)、套接字(Socket)
套接字,源IP地址和目的IP地址以及源端口号和目的端口号的组合称为套接字。其用于标识客户端请求的服务器和服务。套接字分为以下两类:
- 基于文件型:通信进程都运行在同一台机器的环境中,套接字是基于本地文件系统支持的,一个套接字关联到一个特殊的文件,通信双方通过这个特殊文件的读写实现通信,其原理类似于前面所讲的管道。
- 基于网络型:该类型通常采用的是非对称方式通信,即发送者需要提供接收者命名。通信双发的进程运行在不同的主机的网络环境下,被分配了一堆套接字,一个属于接收进程(或服务进程),一个属于发送进程(或客户进程)。
优势:不仅适用于同一台计算机内部的进程通信,也适用于网络环境中不同计算机间的进程通信。
java编程示意图:
socket连接的过程中如果使用的是TCP连接需要在连接的时候进行”三次握手“,断开连接的时候需要进行”四次分手“。
(2)、远程过程调用和远程方法调用
远程过程(函数)RPC(RemoteProcedure Call),是一个通信协议,用于通过网络连接的系统。该协议允许运行于一个主机(本地)系统上的进程调用另外一台主机(远程)系统上的进程,而对程序员表现为常规的过程调用,无需额外的编程。
负责处理远程过程调用的进程有两个,一个是本地客户进程,另一个是远程服务器进程,这两个进程通常也被称为网络守护进程。主要负责在网络间的进程传递,一般情况下,这两个进程都是处于阻塞状态,等待消息。
名词解析:
存根:在本地客户端,每个能够独立运行的远程过程都拥有一个客户存根,本地进程调用远程过程实际是调用该过程关联的存根;与此类似,在每个远程进程所在的服务器端,其所对应的实际可执行的进程也存在一个服务器存根与其关联。本地客户存根与对应的远程服务器存根一般也是处于阻塞状态,等待消息。
主要步骤:
- 本地过程调用者以一般方式调用远程过程在本地关联的客户存根,传递相应的参数,然后将控制权转移给客户存根;
- 客户存根执行,完成包括过程名和调用参数等信息的消息建立,将控制权转移给本地客户进程;
- 本地客户进程完成与服务器的消息传递,将消息发送给远程服务器进程;
- 远程服务器进程接收信息后转入执行,并根据其中的远程过程名找到对应的服务器存根,将消息转给该存根;
- 该服务器存根接收到消息后,由阻塞状态转入执行状态,拆开消息从中取出过程调用的参数,然后以一般方式调用服务器上关联的过程;
- 在服务器端的远程过程运行完毕后,将结果返回给与之关联的服务器存根;
- 该服务器存根获得控制权执行,将结果打包为消息,并将控制权转移给远程服务器进程;
- 远程服务器进程将消息发送会客户端;
- 本地客户进程接收到消息后,根据其中的过程名将消息存入关联的客户存根,再将控制权转移给客户存根;
- 客户存根从消息中取出结果,返回给本地调用者进程,并完成控制权的转移。
上面的主要作用在于:将客户过程的本地调用转化为客户存根,再转化为服务器过程的本地调用,对客户与服务器来说,它们的中间步骤是不可见的,因此,调用者在整个过程中并不知道该执行时在远程还是在本地。