1.1管程
管程的定义
-
管程是由过程、变量及数据结构等组成,它们共同构成了一个特殊的模块或软件包。进程可以在任意时刻调用管程中的过程,但不允许使用管程外的过程来访问管程内的数据结构。
-
管程中在任一时刻只能有一个活跃进程,这一特性可以帮助管程有效地实现互斥
-
管程是一种高级同步原语
管程的工作方式
当一个进程调用管程中的过程时,该过程中的前几条指令将检查管程中当前是否有其他活跃进程。若有,则新到的调用进程被阻塞,等待当前在管程中的其他活跃进程推出管程时将其唤醒;若无,则新到的调用进程立刻进入管程。
管程与进程的区别
-
虽然二者都定义了数据结构,但进程定义的是私有数据结构PCB,而管程定义的是公共数据结构,如条件变量等
-
二者都存在对各自数据结构上的操作,但进程是顺序执行的,而管程则是进行同步操作和初始化操作
-
进程是为了保证系统并发而设计的,管程则是为了解决共享资源的互斥
-
进程通过调用管程中的过程来进行共享数据结构的操作,该过程就表现为进程的子程序,因此进程是主动的,管程是被动的
-
进程间可并发,管程作为子程序不能与其调用者并发
-
进程具有动态性和生命周期,而管程只是一个资源管理模块,供进程调用。
条件变量
在管程中,除了完成互斥外,还要保证能将无法继续运行的进程正确阻塞。因此,需要引入条件变量(condition variable)以及对其的一对wait、signal操作。
-
x.wait
表示正在调用管程的进程因x条件需要被阻塞或挂起,该进程在执行wait操作时将自己插入x条件的等待队列中,并释放管程。此时其它进程可以使用该管程完成自身工作,当x条件产生变化时,系统调度程序将选择等待队列中的一个进程继续执行。 -
x.signal
表示正在调用管程的进程发现x条件发生了变化,则使用signal操作唤醒一个因x条件被阻塞或挂起的进程。
条件变量并非计数器,不能像信号量一样累积信号以便将来使用。
1.2进程通信
进程通信的概念
进程通信指的是进程间的信息交换。
所谓高级进程通信,是指用户可直接利用操作系统所提供的一组通信原语,高效地传送大量数据的一种通信方式。
进程通信对用户是透明的。
进程通信的方式
高级通信机制可以分为三大类:
-
共享存储系统
-
消息传递系统
-
管道通信系统
共享存储器系统
-
基于共享数据结构的通信方式:
-
在该方式中,操作系统只提供共享存储器,对共享的公共数据结构的定义及进程间的同步处理都要由程序员完成,这种方式是低效的,只能传递相对少量的数据。
-
-
基于共享存储区的通讯方式:
-
在该方式中,操作系统要将存储器中的一个子空间用作共享存储区,各进程都可以对该存储区进行读写操作,每个进程都可以读到其它合作进程放入该区的数据。
-
消息传递系统
-
直接通信方式:发送进程间的数据——消息为单位,程序员直接利用系统提供的一组通信命令来实现通信
-
发送进程直接利用send原语将消息发送给目标进程,此时要求发送和接收两方都要以显式方式提供对方的标识符
-
-
间接通信方式:发送进程把消息发送到某个中间实体(信箱)中,接收进程从中间实体中取得消息
-
使用共享数据结构的实体,发送进程用该实体暂存发送给目标进程的消息,接收进程则从该实体中提取发送给自己的消息
-
信箱:私有信箱(用户创建,自身组成部分)、公用信箱(操作系统创建,系统核准进程使用)、共享信箱(进程创建,有权共享名单进程使用)
-
信箱只允许核准用户读取信息,可实现实时通信和非实时通信
-
消息:消息头、消息体(实际要发送的信息)
-
-
消息传递机制可以实现不同主机间多个CPU上进程的通信。这种方式需要使用两条原语send和receive来发送和接收格式化的消息(message)
-
send原语用来向一个指定目标发送一条消息
-
Send(receiver,message)
-
-
receive原语用来从一个指定目标接收一条消息
-
Receive(send,message)
-
管道通信系统
管道通信是一种以文件系统为基础实现的适用于在进程之间实现大量数据传送的通信方式,是指连接一个接收(读)进程和一个发送(写)进程以实现它们之间通信的一个特殊的共享文件,又称为pipe文件、管线
-
读进程和写进程互斥地访问管道
-
读进程和写进程之间存在进程同步
-
读进程和写进程同时存在,才能进行通信
消息缓冲队列通信机制
消息缓冲区是进程通信的一个基本单位,每当发送进程预发送消息时,便形成一个消息缓冲区,再发送给指定的接收进程。
消息缓冲队列通信机制中的相关数据结构
发送原语:
Procedure send(receiver,a)
Begin
申请缓冲区;
a→新申请消息缓冲区;
Wait(mutex);
消息缓冲区→接收进程消息队列;
Signal(mutex);
Signal(sm);
end
接收原语:
Procedure receive(b)
Begin
Wait(sm);
Wait(mutex);
摘下消息队列中的消息i;
Signal(mutex);
i→接收区b;
释放缓冲区;
end