1. PV 处理过程
依据对临界区访问过程的分析,信号量机制中P 原语相当于进入区操作,V 原语相当于退出区操作。下面来分析操作系统对这两个原语操作的处理过程。
(1) P 原语所执行的操作可用下面函数wait(s)来描述。
wait(s)
{
— s.count;//表示申请一个资源
If (s.count <0)//表示没有空闲资源
{
调用进程进入等待队列s.queue;
阻塞调用进程;
}
}
(2)V 原语所执行的操作可用下面函数signal(s)来描述。
signal(s)
{
++s.count;//表示释放一个资源
if(s.count<=0)//表示有进程处于阻塞状态
{
从等待队列s.queue 中取出头一个进程P;
进程P 进入就绪队列;
}
}
利用操作系统提供的信号量机制,可实现临界资源的互斥访问。在使用信号量进行共享资源访问控制时,必须成对使用P 和V 原语。遗漏 P 原语则不能保证互斥访问,遗漏V 原语则不能在使用临界资源之后将其释放给其他等待的进程。P、V 原语的使用不能次序错误、重复或遗漏。
2. 前趋关系
利用操作系统提供的信号量机制可实现进程间的同步,即所谓的前趋关系。
3.管程
一个管程是一个由过程、变量及数据结构等组成的集合,它们组成一个特殊的模块或软件包。进程可在任何需要的时候调用管程中的过程,但它们不能在管程之外声明的过程中直接访问管程内的数据结构。一个管程由4 个部门组成:管程名称,共享数据的说明,对数据进行操作的一组过程和对共享数据赋初值的语句。管程能保障共享资源的互斥执行。
为了保证管程共享变量的数据完整性,规定管程互斥进入;进程间同步关系:一个管程定义了一个数据结构和能为并发进程所执行(在该数据结构上)的一组操作,这组操作能同步进程和改变管程中的数据。任意时刻管程中只能有一个活跃进程,这一特性使管程能有效地完成互斥。
4. 解决进程通信3 类方案
解决进程之间的大量信息通信的问题有3 类方案:共享内存、消息机制以及通过共享文件进行通信,即管道通信。
4.1 共享内存
在相互通信的进程之间设有一个公共内存区,一组进程向该公共内存中写,另一组进程从公共内存中读,通过这种方式实现两组进程间的信息交换。
4.2 消息机制
进程在运行过程中,可能需要与其他的进程进行信息交换,于是进程通过某种手段发出自己的消息或接收其他进程发来的消息。
(1) 消息缓冲区通信机制:① 消息缓冲区,这是一个由消息长度、消息正文、发送者、消息队列指针组成的数据结构;② 消息队列首指针m_q,一般保存在PCB 中;③ 互斥信号量m_mutex,初值为1,用于互斥访问消息队列,在PCB 中设置;④ 同步信号量m_syn,初值为0,用于消息计数,在PCB 中设置。
(2)为实现消息缓冲通信,要利用发送消息原语(send)和接收消息原语(receive)。
① 发送消息原语 send(receiver,a)。
发送进程调用send 原语发送消息,调用参数receiver 为接收进程名,a 为发送进程存放消息的内存
区的首地址。send 原语先申请分配一个消息缓冲区,将由a 指定的消息复制到缓冲区,然后将它挂入接收进程的消息队列,最后唤醒可能因等待消息而等待的接收进程。
send 原语描述如下:send(R,M)
{
根据R 找接收进程,如果没找到,则出错返回;
申请空缓冲区P(s_b);
P(b_mutex);
取空缓冲区;
V(b_mutex);
把消息从M 处复制到空缓冲区;
P(m_mutex);
根据 m _ q,把缓冲区挂到接收进程的消息链链尾;
V(m_mutex);
V(m_syn);
}
其中,s_b 是空缓冲区个数,初值为 n,b_mutex 是空缓冲区的互斥信号量,初值为1。
② 接收消息原语receive(a)。
接收进程调用receive 原语接收一条消息,调用参数a 为接收进程的内存消息区。receive 原语从消息队列中摘下第一个消息缓冲区,并复制到参数a 所指定的消息区,然后释放该消息缓冲区。若消息队列为空,则阻塞调用进程。
4.3 信箱通信
以发送信件以及接收回答信件为进程间通信的基本方式。好处:发送方和接收方不必直接建立联系,没有处理时间上的限制。发送方可以在任何时间发信,接收方也可以在任何时间收信。
规则:① 若发送信件时信箱已满,则发送进程应被置成“等信箱”状态,直到信箱有空时才被释放。② 若取信件时信箱中无信,则接收进程应被置成“等信件”状态,直到有信件时才被释放。
4.4 管道通信
① 管道通信是连接两个进程之间的一个打开的共享文件,专用于进程之间进行数据通信。
② 管道通信的基础是文件系统。
③ 在对管道文件进行读写操作的过程中,发送进程和接收进程要实施正确的同步和互斥,以确通信的正确性。
④ 管道通信具有传送数据量大的优点,但通信速度较慢。