CoderMrWu

生活诚可期,爱情价更高!

操作系统的进程通信是一个什么过程呢?

一个进程在运行过程中,可能需要与其他进程进行信息交换。进程间交换的信息量可多可少,少的只是交换一些已定义的状态值或数值,例如信号量和P、V操作;多的则可交换大量信息。P、V操作是一类低级通信原语,不能承担进程间大量信息的交换任务,因此需要引入新的通信原语,解决大量信息交换问题。

解决进程之间的大量信息通信的问题有三类方案:共享内存、消息机制以及通过共享文件进行通信,即管道通信。这三种方式可以称为高级通信原语,它们不仅要保证相互制约的进程之间的正确关系,还要同时实现进程之间的信息交换。

一、共享内存

在相互通信的进程之间设有一个公共内存区,一组进程向该公共内存中写,另一组进程从公共内存中读,通过这种方式实现两组进程间的信息交换

这种通信模式需要解决两个问题:第一个问题是怎样提供共享内存;第二个是公共内存中的读写互斥问题。操作系统一般只提供要共享的内存空间,而处理进程间在公共内存中的互斥关系则是程序开发人员的责任

二、消息机制

消息机制是用于进程间通信的高级通信原语之一。进程在运行过程中,可能需要与其他的进程进行信息交换,于是进程通过某种手段发出自己的消息或接收其他进程发来的消息

这种方式类似于人们通过邮局收发信件来实现交换信息的目的。至于通过什么手段收发消息,就像人们选择平信还是航空信一样,是一种具体的消息传递机制。

1.消息缓冲通信

消息缓冲通信技术是由 Hansen首先提出的,其基本思想是:根据“生产者—消费者”原理,利用内存中公用消息缓冲区实现进程之间的信息交换

内存中开辟了若干消息缓冲区,用以存储消息。每当一个进程(发送进程)向另一个进程(接收进程)发送消息时,便申请一个消息缓冲区,并把已准备好的消息送到缓冲区,然后把该消息缓冲区插入到接收进程的消息队列中,最后通知接收进程。接收进程收到发送进程发来的通知后,从本进程的消息队列中摘下一消息缓冲区,取出所需的信息,然后把消 息缓冲区还给系统。系统负责管理公用消息缓冲区以及消息的传递。

一个进程可以给若干个进程发送消息,反之,一个进程可以接收不同进程发来的消息。

显然,进程中关于消息队列的操作是临界区。当发送进程正往接收进程的消息队列中添加一条消息时,接收进程不能同时从该消息队列中取出消息;反之也一样。

消息缓冲区通信机制包含以下列内容。

1)消息缓冲区,这是一个由以下几项组成的数据结构:①消息长度; ②消息正文; ③发送者; ④消息队列指针。

2)消息队列首指针m_q,一般保存在PCB中。

3)互斥信号量m_ mutex,初值为1,用于互斥访问消息队列,在PCB中设置。

4)同步信号量m_syn,初值为0,用于消息计数,在PCB中设置。

为实现消息缓冲通信,要利用发送消息原语(send)和接收消息原语( receive)。

5)发送消息原语send( receiver,a):

发送进程调用send原语发送消息,调用参数 receiver为接收进程名,a为发送进程存储消息的内存区的首地址。send原语先申请分配一个消息缓冲区,将由a指定的消息复制到缓冲区,然后将它挂入接收进程的消息队列,最后唤醒可能因等待消息而等待的接收进程。

send原语描述如下:

send(R, M)

根据R找接收进程,如果没找到,则出错返回;

申请空缓冲区P(sb);

P(b mutex)

取空缓冲区;

V(b- mutex);

把消息从M处复制到空缓冲区;

P(m mutex)

根据m_q,把缓冲区挂到接收进程的消息链链尾

V(m mutex);

V(m_syn);

其中,s_b是空缓冲区个数,初值为n;b_ mutex是空缓冲区的互斥信号量,初值为1。

6)接收消息原语 receive(a):

接收进程调用 receive原语接收一条消息,调用参数a为接收进程的内存消息区。Re-ceive原语从消息队列中摘下第一个消息缓冲区,并复制到参数a所指定的消息区,然后释放该消息缓冲区。若消息队列为空,则阻塞调用进程。

2.信箱通信

为了实现进程间的通信,可以设立一个通信机构——信箱,以发送信件以及接收回答信件为进程间通信的基本方式

当一个进程希望与另一进程通信时,就创建一个链接两个进程的信箱,发送进程把信件投入信箱,而接收进程可以在任何时刻取走信件。

一个信箱的结构可以由“信箱说明”和“信箱体”两部分组成。

在“信箱说明”中,一般有如下的数据结构。

可存信件数”是在设立信箱时预先确定的,表明信箱的容量大小。

已有信件数”指出信箱中已有信件的数量。

通过“可存信件数”和“已有信件数”就能判别信箱是否满和信箱中是否有信件。

可存信件的指针”指示当前可存入一封信的位置。该指针的初始值为指向可存第一封信的位置。

当存入一封信后,则应该修改“已有信件数”和“可存信件的指针”。相应地,若信箱中有信,则每次从中取出一封信,也应该修改“已有信件数”和“可存信件的指针”。

为了实现信箱通信,必须提供相应的原语,如创建信箱原语、撤销信箱原语、发送信件原语和接收信件原语等

例如,进程A要与进程B通信,进程A就通过创建信箱原语,创建一个连接进程A和进程B的信箱。有了这个信箱,进程A可以通过发送信件原语将信件发送到信箱中,系统将保证进程B可在任何时刻调用接收信件原语,取走信箱中的信件,而不会丢失,如图48所示

图48表示的是一个发送者和一个接收者单向通信的例子。在进程A发送信件之前,信箱中至少应该有空位置,可以存放信件;同样,在进程B接收信件之前,信箱中应该有信件,否则进程应该等待。

采用信箱通信的最大好处是,发送方和接收方不必直接建立联系,没有处理时间上的限制。发送方可以在任何时间发信,接收方也可以在任何时间收信。

由于发送方和接收方都是独立工作的,如果发得快而收得慢,则信箱会溢出。相反,如果发得慢而收得快,则信箱会变空。因此,为避免信件丢失和错误地送出信件,一般而言通信应有如下的规则。

1)若发送信件时信箱已满,则发送进程应被置“等信箱”状态,直到信箱有空时才被释放。

2)若取信件时信箱中无信,则接收进程应被置成“等信件”状态,直到有信件时才被释放。

下面举一个“send”原语和“ receive”原语的例子如下

send(Box,L):把信件L送到指定的信箱Box中。

功能:查信箱Box,若信箱未满则把信件L送入信箱,且释放“等信件”者;若信箱已满,置发送信件进程为“等信箱”状态。

receive(Box, Address):从指定信箱Box中取出一封信,存储到指定的地址Address中。

功能:查指定信箱Box,若信箱中有信,则取出一封信存于 Address中,且释放“等信箱”者;若信箱中无信件,则置接收信件进程“等信件”状态。

3.管道通信

管道(Pipe)通信首先出现在UNⅨ操作系统中。作为UNⅨ的一大特色,管道通信立即引起了人们的兴趣。由于管道通信的有效性,一些系统继UNIX之后相继引入了管道技术,管道通信是一种重要的通信方式。

所谓管道,就是连接两个进程之间的一个打开的共享文件,专用于进程之间进行数据通信。发送进程可以源源不断地从管道一端写入数据流,每次写人的信息长度是可变的;接收进程在需要时可以从管道的另一端读出数据,读出单位长度也是可变的。显然,管道通信的基础是文件系统。

在对管道文件进行读写操作过程中,发送进程和接收进程要实施正确的同步和互斥,以确保通信的正确性。管道通信机制中的同步与互斥都由操作系统自动进行,对用户是透明的。

管道通信具有传送数据量大的优点,但通信速度较慢。

更多免费自考课程请关注ww1.fzydk.com。

点赞