转自:https://blog.csdn.net/qq_38499859/article/details/80425044
一.进程通信概述
进程通信是指进程间的信息交换。在进程的互斥与同步中,也在进程之间交换了一些信息,因此不少学者也将他们归为低级进程通信。他们低级的原因在与:① 效率低 ② 通信对与用户不透明.
在进程间要传递大量数据是,应当利用OS提供的的高级通信工具,目前,常见的高级通信机制可归为四类:共享存储器,管道通信系统,消息传递系统,客户机-服务机系统.
二.管道通信
1.概述
管道也称共享文件方式,基于文件系统,利用打开的共享文件连接两个相互通信的进程,文件作为缓冲传输介质。
管道就是用于连接读进程和写进程的共享文件,写进程想管道发送字符流。读进程从管道中接受字符流。
2. 管道机制必须提供的协调能力
- 互斥:当一个进程正在等待pipe进行读写操作时,另一个进程必须等待。
- 同步:当写进程把一定数量的数据写入pipe后,便去睡眠等待,直到读进程取走数据后,再把它唤醒。当读进程读到一空pipe时,也应睡眠等待,直至写进程将数据写入管道后,才将它唤醒。
- 对方是否存在:只有确定对方存在是,才能进行通信。
三.消息传递机制
1. 概述
在该机制中,以格式化的消息(message)为通信单位;利用系统为进程提供的两个高级通信原语send和received进行通信,隐藏看通讯的实现细节,对用户是透明的,使用非常方便,是使用最广泛的进程通信机制。
send: 但要进行消息传递时,执行send
receive:当接收者要接收消息是执行receive。
根据实现方式不同,可进一步将他们分为两种:
- 直接通信方式:是指发送进程利用OS提供的发送原语,直接把消息发送给目标进程
- 间接通信方式:是指发送和接收进程,都通过共享中间实体(邮箱)的方式进行消息的发送和接收,完成进程间的通信。
2.直接消息传递系统的实现方式
a.直接通信原语
直接信息传递系统分为两种。
对称寻址方式,这种方式下,发送进程和进程都要求以显式方式提供对方的的标识符,通常,系统提供的原语如下
send(receiver, message);发送一个消息给接受进程
receive(sender,message);接受发送进程的消息
非对称寻址方式,这种方式中,接受进程的原语中,并不需要命名发送进程。只填写表示源进程参数。原语如下:
send(P,message);
recrive(id,message);
b.消息的格式
消息的格式常用的就是较短的定长消息格式,和较长的可变的消息格式。定长的消息格式处理简单,存储空间开销少。可变的消息格式方便用户的使用,但是处理和存储空间需要更多的更大的开销.
c.通路链路
为了在发送进程和接受进程自己能进行通信,必须在两者之间建立一条通信链路。
有两种方式建立通信链路:
第一种:由发送进程在通信之前用显示的"通信连接"命令请求系统为之建立一条通信链路。在链路使用完后拆除链路。(主要用于计算机网络)
第二种:发送进程无需明确提出建立链路的请求,只需要利用系统提供的发送命令原因,系统会自动为之建立一条链路。
3.直接消息传递系统实例
a.数据结构
在消息缓冲队列通信方式中,主要利用的数据结构是消息缓冲区
描述如下:
typedef struct message_buffer{
int sender; //发送者进程标识符
int size; //消息长度
char *text; /消息正文
struct message_buffer *next; //指向下一个消息缓冲区的指针
}
在PCB有关通信的数据项中。加入以下项
typedef struct processcontrol_block{
···
struct message_buffer *mq;//消息队列首指针.
semaphore muter; //消息队列互斥量
semaohore sm; //消息队列资源信号量
···
}PCB
b.发送原语
发送原语描述如下:
void send(receiver,a){ //receiver为接受进程的标识符,a为发送区间首地址
getbuf(a.size,i); //根据a.size申请缓冲区。
i.sender = a.sender;
i.size = a.size;
copy(i.text,a.text);//将发送区a的信息复制到消息缓冲区i中
i.next=0;
getid(PCBset,receiver.j);//获得接受进程内部的标识符;
wait(j.mutex);
insert(&j.mq,i);//将小修缓冲区插入消息队列中
signal(j.mutex);
a=signal(j.sm);
}
c.接收原语
接受原语描述如下:
void receive(b){
j = internal name;//j为接收进程的标识符。
wait(j.sm);
wait(j.mutex);
removce(j.mq,i); //将消息队列中第一个消息移出。
signel(j.mutex);
b.sender = i.sender;
b.size = i.size;
cope(b.tezt,i.text); //将消息缓存区i中的信息复制到b中
releasebuf(i);
}
四.客户机-服务机系统
前面所述的各种技术,虽然也实现了不同计算机间进程的通信,但客户机——服务器的通信机制,在网络环境的各种应用已成为当前主流,其主要的实现方式分为三类:套接字(Scoket),远程过程调用和远程方法调用。
1. 套接字Scoket
一个套接字就是有关通信标识类型的数据结构,包含了通信目的地,通信使用的端口号,通信网络的传输层协议,进程所在的网络地址,以及针对客户或者服务器所提供的不同的系统调用。通常套接字包括两类:
- 基于文件性:通信进程都运行在一台机器的环境中,套接字是基于本地文件系统的支持,一个套接字关联到一个特殊的文件,双方文件基于这个特殊文件进行读写。
- 基于网络型:这种类型通常采用非对称方法通信,即发送者需要提供接收者的命名。通信双方的进程运行的在不同主机的网络环境下,被分配了一对套接字。
套接字的优势在于,它不仅适用于同一台计算机内部的进程通信,也适用于网络环境中不同计算机间的进程通信。
2. 远程过程调用和远程方法调用
远程过程调用,是一个通信协议,用于通过网络连接的系统。该协议允许运行一台主机系统上的进程调用另一台主机系统上的进程,而对程序员表现为常规的进程调用,无需为此额外编程。
五.参考资料
《操作系统 第四版》
进程间通信(IPC)介绍