第2章进程管理_第1页
第2章进程管理_第2页
第2章进程管理_第3页
第2章进程管理_第4页
第2章进程管理_第5页
已阅读5页,还剩152页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第二章进程管理2.1进程的基本概念2.2进程控制2.3进程同步2.4经典进程的同步问题2.6进程通信2.7线程2.1进程的基本概念

进程是操作系统中最基本、最重要的概念.

为什么引入“进程”概念?程序≠进程?直接原因:多道程序系统出现

手段:程序的并发执行若干个程序同时在系统中执行,这些程序的执行在时间上是重叠的,一个程序的执行尚未结束,另一个程序的执行已经开始目的:充分利用系统资源

=

引入“进程”原因:描述和管理并发执行为什么引入“进程”?程序顺序执行程序顺序执行:

#include“myhead.h”

int

main(int

argc,char*argv[]){……

while(TRUE){从终端等待读入数据到i;根据i数据进行计算;取出计算结果并写到磁带上;}return0;}

特征:顺序性,封闭性,可再现性I1C1P1I2C2P2ICP程序:指令或语句序列,体现了某种算法,所有程序是顺序的顺序环境:在计算机系统中只有一个程序在运行,这个程序独占系统中所有资源,其执行不受外界影响为什么引入“进程”?程序段并发执行I1C1P1程序段并发执行:

ICPT程序段ICP

#include“myhead.h”

int

main(int

argc,char*argv[]){……

while(TRUE){从终端等待读入数据到i;根据i数据进行计算;取出计算结果并写到磁带上;}return0;}

I2C2P2I3C3P3间断性失去封闭性不可再现性可再现性并发性某种封闭?进程

较典型的进程定义有:(1)进程是程序的一次执行。(2)进程是一个程序及其数据在处理机上顺序执行时所发生的活动。(3)进程是程序在一个数据集合上运行的过程,它是系统进行资源分配和调度的一个独立单位。在引入了进程实体的概念后,我们可以把传统OS中的进程定义为:“进程是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位”。进程特征结构特征:由程序段、数据段、进程控制块三部分组成动态性:进程是程序的执行并发性:多个进程可同存于内存中,能在一段时间内同时运行独立性:独立运行的基本单位,独立获得资源和调度的基本单位。异步性:各进程按各自独立的不可预知的速度向前推进进程同程序的比较?程序是指令的有序集合,其本身没有任何运行的含义,是一个静态的概念。而进程是程序在处理机上的一次执行过程,它是一个动态的概念。程序可以作为一种软件资料长期存在,而进程是有一定生命期的。程序是永久的,进程是暂时的。进程更能真实地描述并发,而程序不能进程具有创建其他进程的功能,而程序没有同一程序同时运行于若干个数据集合上,它将属于若干个不同的进程。也就是说同一程序可以对应多个进程

进程的分类:系统进程用户进程(系统进程优先于用户进程)进程结构进程实体=

程序段+相关数据段+PCB(进程控制块)进程:是进程实体的运行过程,是系统进行资源分配和调度的一个独立单位进程映象(进程结构)用户程序段用户数据段进程控制块PCB(执行上下文)控制进程所需的数据(进程属性),包括:进程标识符信息(内、外、用户等)处理器状态信息(寄存器、PC、PSW、堆栈指针等)进程调度信息(状态、优先级、事件、其它信息)进程控制信息(程序/数据外存地址、资源清单、PCB链接指针、同步与通信机制等)进程控制块(ProcessControlBlock)作用:是使一个在多道程序环境下不能独立运行的程序(含数据),成为一个能独立运行的基本单位,一个能与其它进程并发执行的进程。概念:系统为了管理进程设置的一个专门的数据结构,用它来记录进程的外部特征,描述进程的运动变化过程OS利用PCB来控制和管理进程。PCB是系统感知进程存在的唯一标志。进程与PCB是一一对应的。进程控制块中的信息进程标识符系统给每个进程定义了一个标识该进程的非负整数,称作进程标识符。当某一进程终止后,其标识符可以重新用作另一进程的标识符。不过,一个标识符所代表的进程在任何时刻都是惟一的。处理机状态处理机的各种寄存器中的内容。以便于进程从断点继续执行。①通用寄存器②指令计数器③程序状态字PSW④用户栈指针进程控制块中的信息进程调度信息与进程调度和进程对换有关,包括:①进程状态,②进程优先级,③所需的其它信息,④事件,即阻塞原因。

进程控制信息①程序和数据的地址②进程同步和通信机制③资源清单④链接指针进程控制块中的信息进程标识符内部标识符。OS为每个进程赋予惟一的数字标识符,系统使用。外部标识符。由创建者提供,由用户(进程)在访问该进程时使用。处理机状态处理机的各种寄存器中的内容。以便于进程从断点继续执行。①通用寄存器②指令计数器③程序状态字PSW④用户栈指针进程调度信息与进程调度和进程对换有关,包括:①进程状态,②进程优先级,③所需的其它信息,④事件,即阻塞原因。进程控制信息①程序和数据的地址②进程同步和通信机制③资源清单④链接指针进程控制块的组织方式

PCB表:系统把所有PCB组织在一起,并把它们放在内存的固定区域,就构成了PCB表

PCB表的大小决定了系统中最多可同时存在的进程个数,称为系统的并发度(注:多道程序中的多道与系统并发度不同)

PCB怎么组织在一起的?PCB表的数据结构?进程控制块的组织方式1)链接方式

1、相同状态的进程PCB组成一个链表,不同状态对应多个不同的链表2、就绪链表、阻塞链表进程控制块的组织方式2)索引方式对具有相同状态的进程,分别设置各自的PCB索引表,表明PCB在PCB表中的地址回顾为什么引入“进程”概念?进程的特征、定义进程控制块的作用、包括的信息、组织形式目的:“进程”概念进程的状态及转换进程有三种基本状态(不同系统设置的进程状态数目不同)。就绪状态(Ready)运行状态(Running)阻塞状态(Wait/Blocked)执行态(Running): 进程占有CPU,并在CPU上执行就绪态(Ready):

一个进程已经具备执行条件,但由于无CPU暂时不能执行的状态(当调度给其CPU时,立即可以执行)阻塞态(Blocked):等待态、挂起态、封锁态冻结态、睡眠态

指进程因等待某种事件的发生而暂时不能执行的状态(即使CPU空闲,该进程也不可执行)执行就绪阻塞进程的状态及其转换

进程状态转换:在进程执行过程中,由于进程自身进展情况及外界环境的变化,这三种基本状态可以依据一定的条件相互转换

就绪—执行

执行—就绪

执行—阻塞

阻塞—就绪进程转换就绪-->执行调度程序选择一个新的进程执行执行-->就绪执行进程用完了时间片执行进程被中断,因为一高优先级进程处于就绪状态进程转换(续1)执行-->阻塞当一进程必须等待时OS尚未完成服务对一资源的访问尚不能进行初始化I/O且必须等待结果等待某一进程提供输入(IPC)阻塞-->就绪当所等待的事件发生时其他状态:新状态,终止状态挂起状态,将就绪/阻塞分活动,静止(调节负载,对换,父进程,操作系统,终端用户)新建状态OS已完成为创建一进程所必要的工作已构造了进程标识符已创建了管理进程所需的表格但还没有允许成为就绪进程(尚未同意)因为资源有限终止状态终止后进程移入该状态它不再有执行资格表格和其它信息暂时由辅助程序保留五状态进程模型七状态进程模型活动挂起事件发生事件发生等待事件挂起调度超时释放活动挂起新状态转换(中期调度)活动阻塞-->静止阻塞(挂起)当所有进程都阻塞,OS会安排空间让一就绪进程进入内存静止阻塞-->静止就绪(释放)当等待的事件发生时(状态信息已在OS中)静止就绪-->活动就绪(激活)当内存中没有就绪进程时活动就绪-->静止就绪(挂起,较少见)当没有被阻塞的进程,而为了性能上的考虑,必须释放一些内存时图2-6具有挂起状态的进程状态图某进程在运行过程中需要等待从磁盘上读入数据,此时该进程的状态将()。A、从就绪变为运行B、从运行变为就绪C、从运行变为阻塞D、从阻塞变为就绪有没有以下这些状态转换,为什么?1)等待—运行;2)就绪—等待如果系统中有N个进程,执行的进程最多几个,最少几个;就绪进程最多几个最少几个;阻塞进程最多几个,最少几个?2.2进程控制

进程控制就是对系统中的所有进程实施管理,创建、撤消进程以及完成进程各状态之间的转换。进程控制一般由原语来实现。

原语

primitiveor

atomicaction定义:是一种特殊的系统功能调用,它可以完成一个特定的功能,其特点是原语执行时不可被中断。特点:原子操作,不可分割,要么全做,要么全不做。由若干多机器指令构成的完成某种特定功能的一段程序,它的执行必须是连续的,在执行过程中不允许被中断。常用的进程控制原语

创建原语终止原语阻塞原语、唤醒原语

fork,execexitwait系统调用?进程树?进程树父子进程:继承资源;归还资源。进程树在UNIX系统中,只有0进程是在系统引导时被创建的。在系统初启时由0进程利用fork()创建1进程,以后0进程变成对换进程,1进程成为系统中的始祖进程。系统中除0进程外的所有进程都是用fork()创建的。

进程创建-原因系统内核需要:用户登录,作业调度,提供服务用户应用请求:进程自己要求创建,如父进程创建子进程,创建输入进程、处理进程、输出进程并发执行,以加速任务完成。进程创建-过程申请空白PCB,赋予一个进程内部标识符为新进程分配资源如内存初始化进程控制块将新进程插入就绪队列

思考为什么创建进程要用原语来实现?fork():创建一个新进程的函数参数定义:intfork()系统调用格式:pid=fork()fork()返回值:0,>0,-1

用户使用系统调用fork创建一个进程。核心为完成系统调用fork要进行几步操作。(1)分配新的内存块和内核数据结构(2)复制原来的进程到新的进程(3)向运行进程集添加新的进程(4)将控制返回给两个进程PC…..pid=fork();if(pid==0)

执行子进程代码;elseif(pid>0)

执行父进程代码;else

创建失败处理;

fork()调用前父进程PC…..pid=fork();if(pid==0)

执行子进程代码;elseif(pid>0)

执行父进程代码;else

创建失败处理;其它代码;PC…..pid=fork();if(pid==0)

执行子进程代码;elseif(pid>0)

执行父进程代码;else

创建失败处理;其它代码;fork()调用后父进程子进程程序fork函数实例#include<stdio.h>#include<unistd.h>main(){

pid_t

pid;

printf(“nowonlyoneprocess\n”);

printf(“callingfork…\n”);

pid=fork();

if(!pid)

printf(“Iamachild\n”); elseif(pid>0)

printf(“I’mtheparent,childhaspid%d\n”,pid); else

printf(“Forkfail!\n”);}进程运行

exec函数把一个新程序装入调用进程的内存空间,来改变调用进程的执行代码,从而形成新进程。如果exec调用成功,调用进程将被覆盖,然后从新程序的入口开始执行,这样就产生了一个新的进程,但是它的进程标识符与调用进程相同。

这就是说,exec并没有建立一个与调用进程并发的新进程,而是用新进程取代了原来的进程。所以,在exec调用成功后,没有任何数据返回,这和fork是不一样的。它有六种调用的形式,随着系统的不同并不完全相同。#include<unistd.h>int

execl(constchar*pathname,constchar*arg0,.../*(char*)0*/);int

execv(constchar*pathname,char*constargv

[]);int

execle(constchar*pathname,constchar*arg0,.../*(char*)0,char*constenvp[]*/);int

execve(constchar*pathname,char*constargv

[],char*constenvp

[]);int

execlp(constchar*filename,constchar*arg0,.../*(char*)0*/);int

execvp(constchar*filename,char*constargv

[]);六个函数返回:若出错则为-1,若成功则不返回1.将指定的程序复制到调用它的进程2.将指定的字符串数组作为参数传递给这个程序3.运行这个程序。一个程序中运行另一个程序#include<unistd.h>#include<stdio.h>main(){ char*arglist[3]; arglist[0]=“ls”; arglist[1]=“-l”; arglist[2]=NULL;

execvp(“ls”,arglist);}#include<unistd.h>#include<stdio.h>main(){

execl(“ls”,”ls”,”-l”,NULL);}

系统调用exec和fork时经常结合使用,父进程fork一个子进程,在子进程中调用exec来替换子进程的执行图像,并发地执行一些操作。进程终止-原因

正常结束,异常结束,外界干预进程终止-过程?进程终止-过程根据被终止进程的标识符,从PCB集合中检索出该进程的PCB将进程所拥有的资源交给父进程或系统进程释放PCB

进程可使用系统调用exit()终止自己除了使用exit函数来终止进程外,当进程运行完程序到达main()函数末时,进程会自动终止。当进程在main()函数内执行return语句时,它也会终止。进程的阻塞与唤醒阻塞:当一个进程所期待的某一事件尚未出现时,该进程调用阻塞原语将自己阻塞。进程阻塞是进程的自身的一种主动行为。唤醒:处于阻塞状态的进程是绝不可能叫醒它自己的,它必须由它的合作进程或系统进程用唤醒原语唤醒它。

阻塞与唤醒为一对作用相反的操作。进程阻塞

自己阻塞自己。处于运行状态的进程,在其运行过程中期待某一事件发生,如等待键盘输入、等待磁盘数据传输完成、等待其它进程发送消息,当被等待的事件未发生时,由进程自己执行阻塞原语,使自己由运行态变为阻塞态。

进程唤醒

被阻塞进程所期待的事件发生,或数据已到达,则该进程应被唤醒。唤醒进程为:由事件发生进程唤醒被阻塞进程或由系统进程唤醒阻塞与唤醒为一对作用相反的操作。思考请设想一下进程在什么情况下会变为阻塞状态?阻塞进程在什么情况下会被唤醒?谁来唤醒它?wait函数是实现进程同步的简单手段。调用wait的进程进入睡眠状态直到它的一个子进程退出时或收到一个不能被忽略的信号时被唤醒。如果调用发出时,已经有退出的子进程(这时子进程的状态是僵死状态),该调用立即返回。wait()函数#include<sys/types.h>#include<sys/wait.h>pid_t

wait(int*statloc);函数返回:若成功则为进程ID,若出错则为-12.3进程同步直接的相互制约(资源共享)和间接的相互制约(进程间合作)

同步和互斥并发控制的内容竞争共享某些资源----进程互斥协作完成任务----进程同步通过通信进行协作----进程通信进程的同步(直接作用)进程的同步:synchronism

指系统中多个进程中发生的事件存在某种时序关系,需要相互合作,共同完成一项任务。具体说,一个进程运行到某一点时要求另一伙伴进程为它提供消息,在未获得消息之前,该进程处于等待状态,获得消息后被唤醒进入就绪态

由于各进程要求共享资源,而有些资源需要互斥使用,因此各进程间竞争使用这些资源,进程的这种关系为进程的互斥

进程的互斥(间接作用)mutualexclusion

临界资源

criticalresource:一次仅允许一个进程访问的资源。进程AB共享一台打印机,若让它们交替使用?临界资源可以是软件资源吗?生产者-消费者01234n-1inoutintn,in=out=0,counter=0;itembuffer[n];空:in=out满:(in+1)modn=out生产者producer:doproduceanitem;whilecounter=ndono-op;

buffer[in]=nextp;in=(in+1)modn;

counter++;while(1);消费者consumer:dowhilecounter=0dono-op;

nextc=buffer[out];out=(out+1)modn;

counter--;consumeanitem;while(1)变量counter就是临界资源.假设counter=5.counter++;register1=counter;register1=register1+1;counter=register1;counter--;register2=counter;register2=register-1;counter=register2;结果:counter=5假设counter=5.

register1∶=counter;(register1=5)register1∶=register1+1;(register1=6)register2∶=counter;(register2=5)register2∶=register2-1;(register2=4)counter∶=register1;(counter=6)counter∶=register2;(counter=4)

结果:counter≠5,发生错误。临界区criticalsection:在每个程序中,访问临界资源的那段程序。

若能保证每个进程互斥地进入自己的临界区==就可实现进程对临界资源的互斥访问。怎样保证并发进程对临界资源的互斥访问?解决互斥访问?

一个进程访问临界资源的程序段:…….

criticalsection;

remaindersection;…………….

exitsectionentrysection资源可用吗?等/占释放资源解决互斥的准则

空闲让进:当无进程在互斥区时,任何有权使用互斥区的进程可进入忙则等待:不允许两个以上的进程同时进入互斥区有限等待:任何进入互斥区的要求应在有限的时间内得到满足

让权等待:处于阻塞状态的进程应放弃占用CPU,以使其他进程有机会得到CPU的使用权信号量机制整型信号量记录型信号量AND型信号量信号量集资源数量+1释放Signal-V资源可用?Y资源数量-1等待N占用Wait-P原子操作应用环境

一个进程访问临界资源的程序段:…….

criticalsection;

remaindersection;…………….

Signal(S)Wait(S)资源可用吗?等/占释放资源用P、V操作解决进程间互斥问题P(mutex)V(mutex)P1P2P3互斥区P(mutex)P(mutex)V(mutex)V(mutex)整型信号量

wait(S):whileS≤0dono-opS∶=S-1;

signal(S):S∶=S+1;忙等记录型信号量引入信号量数据结构,定义如下:

struct

semaphore{

intvalue;

Lqueue;}信号量说明:

semaphores;记录型信号量wait(S)

{

s.value=s.value-1;if(s.value<0){block(S,L); }}

signal(S){

s.value=s.value+1;if(s.value<=0){wakeup(S,L);}}

将该进程状态置为等待状态;将该进程的PCB插入相应的等待队列末尾s.queue;唤醒相应等待队列s.queue中等待的一个进程;改变其状态为就绪态;并将其插入就绪队列该机制遵循了“让权等待”准则记录型信号量

S.value<0时,|S.value|表示在该信号量链表中已阻塞进程的数目;

S.value≥0时,S.value表示可用的资源的数目

signal(S)后,S.value==0,有什么含义?

思考:对于两个并发进程,互斥信号量s.value的取值范围是什么,有什么含义?N个并发进程呢?信号量互斥信号量:申请或释放资源使用权资源信号量:申请或归还资源,表示系统中某类资源的可用个数信号量的使用:

必须置一次且只能置一次初值初值不能为负数

只能执行P、V操作信号量的应用利用信号量实现进程互斥

利用信号量实现前趋关系利用信号量实现前趋关系

利用了wait(s),signal(s)原子地、相反操作特点beginS1;signal(a);signal(b);end;beginwait(a);S2;signal(c);signal(d);end;…..进程互斥互斥信号量mutex这里的临界资源是什么?经典的生产者─消费者问题临界资源:n个缓冲区,互斥信号量mutex表使用权生产者进程不能往“满”的缓冲区中放产品,信号量full表“满”的数量消费者进程不能从“空”的缓冲区中取产品,信号量empty表“空”的数量数据结构

semaphoremutex=1,empty=n,full=0;

item[n]buffer;

intin=0,out=0;生产者

{doproduceraniteminnextp;

P(empty);

P(mutex);

buffer(in)=nextp;in=(in+1)modn

V(mutex);

V(full);while(1);}消费者{do

P(full);

P(mutex);

nextp=buffer(out);out=(out+1)modn

V(mutex);

V(empty);consumetheitem;while(1);}P.V操作讨论1、信号量的物理含义:P(S):表示申请一个资源V(S)表示释放一个资源。

信号量的初值应该大于等于0。S>0表示有S个资源可用S=0表示无资源可用S<0则|S|表示S等待队列中的进程个数2、P.V操作必须成对出现当为互斥操作时,它们同处于同一进程;当为同步操作时,则不在同一进程中出现;如果P(S1)和P(S2)两个操作在一起,那么P操作的顺序至关重要,一个同步P操作与一个互斥P操作在一起时,同步P操作在互斥P操作前,而两个V操作无关紧要3、P.V操作的优缺点优点:简单,而且表达能力强(用P.V操作可解决任何同步互斥问题)缺点:不够安全;P.V操作使用不当会出现死锁;遇到复杂同步互斥问题时实现复杂2.4.2哲学家进餐问题

1.利用记录型信号量解决哲学家进餐问题经分析可知,放在桌子上的筷子是临界资源,在一段时间内只允许一位哲学家使用。为了实现对筷子的互斥使用,可以用一个信号量表示一只筷子,由这五个信号量构成信号量数组。其描述如下:

Varchopstick:array[0,…,4]ofsemaphore;所有信号量均被初始化为1,第i位哲学家的活动可描述为:

repeat wait(chopstick[i]); wait(chopstick[(i+1)mod5]); … eat;… signal(chopstick[i]); signal(chopstick[(i+1)mod5]); … think;untilfalse;可采取以下几种解决方法:(1)至多只允许有四位哲学家同时去拿左边的筷子,最终能保证至少有一位哲学家能够进餐,并在用毕时能释放出他用过的两只筷子,从而使更多的哲学家能够进餐。(2)仅当哲学家的左、右两只筷子均可用时,才允许他拿起筷子进餐。(3)规定奇数号哲学家先拿他左边的筷子,然后再去拿右边的筷子;而偶数号哲学家则相反。按此规定,将是1、2号哲学家竞争1号筷子;3、4号哲学家竞争3号筷子。即五位哲学家都先竞争奇数号筷子,获得后,再去竞争偶数号筷子,最后总会有一位哲学家能获得两只筷子而进餐。2.4.3读者-写者问题1.利用记录型信号量解决读者-写者问题

为实现Reader与Writer进程间在读或写时的互斥而设置了一个互斥信号量Wmutex。另外,再设置一个整型变量Readcount表示正在读的进程数目。由于只要有一个Reader进程在读,便不允许Writer进程去写。因此,仅当Readcount=0,表示尚无Reader进程在读时,Reader进程才需要执行Wait(Wmutex)操作。若wait(Wmutex)操作成功,Reader进程便可去读,相应地,做Readcount+1操作。同理,仅当Reader进程在执行了Readcount减1操作后其值为0时,才须执行signal(Wmutex)操作,以便让Writer进程写。又因为Readcount是一个可被多个Reader进程访问的临界资源,因此,应该为它设置一个互斥信号量rmutex。读者-写者问题可描述如下:Var

rmutex,wmutex:semaphore∶=1,1;

Readcount:integer∶=0;begin

parbegin

Reader:beginrepeat

wait(rmutex);ifreadcount=0thenwait(wmutex);

Readcount∶=Readcount+1;

signal(rmutex);…performreadoperation;…

wait(rmutex);

readcount∶=readcount-1;ifreadcount=0thensignal(wmutex);

signal(rmutex);untilfalse;endwriter:beginrepeat

wait(wmutex);performwriteoperation;

signal(wmutex);untilfalse;end

parend

end2.5进程的同步机制──管程管程的提出采用PV同步机制来编写并发程序,对于共享变量及信号量变量的操作将被分散于各个进程中缺点:(1)易读性差,因为要了解对于一组共享变量及信号量的操作是否正确,则必须通读整个系统或者并发程序(2)不利于修改和维护,因为程序的局部性很差,所以任一组变量或一段代码的修改都可能影响全局(3)正确性难以保证,因为操作系统或并发程序通常很大,要保证这样一个复杂的系统没有逻辑错误是很难的管程:一种同步机制管程定义:指关于共享资源的数据及在其上操作的一组过程或共享数据结构及其规定的所有操作系统按资源管理的观点分解成若干模块,用数据表示抽象系统资源,同时分析了共享资源和专用资源在管理上的差别,按不同的管理方式定义模块的类型和结构,使同步操作相对集中,从而增加了模块的相对独立性管程的四个组成部分:管程的名称局部于管程内的共享数据结构说明对该数据结构进行操作的一组过程/函数初始化语句管程的形式TYPEmonitor_name=MONITOR;共享变量说明

define本管程内所定义、本管程外可调用的过程(函数)名字表

use本管程外所定义、本管程内将调用的过程(函数)名字表PROCEDURE过程名(形参表);过程局部变量说明;BEGIN

语句序列;END;......FUNCTION函数名(形参表):值类型; 函数局部变量说明;

BEGIN

语句序列;

END;......BEGIN

共享变量初始化语句序列;END;共享数据一组操作过程/函数

…………初始化代码条件队列进入其它队列

管程的三个主要的特性:(一)模块化,一个管程是一个基本程序单位,可以单独编译(二)抽象数据类型,管程是一种特殊的数据类型,其中不仅有数据,而且有对数据进行操作的代码(三)信息掩蔽,管程是半透明的,管程中的外部过程(函数)实现了某些功能,至于这些功能是怎样实现的,在其外部则是不可见的

管程有如下几个要素:(一)管程中的共享变量在管程外部是不可见的,外部只能通过调用管程中所说明的外部过程(函数)来间接地访问管程中的共享变量(二)为了保证管程共享变量的数据完整性,规定管程互斥进入(三)管程通常是用来管理资源的,因而在管程中应当设有进程等待队以及相应的等待及唤醒操作管程和进程的异同点:(1)设置进程和管程的目的不同(2)系统管理数据结构进程:PCB

管程:等待队列(3)管程被进程调用(4)管程是操作系统的固有成分,无创建和撤消2.6进程通信

P.V操作实现的是进程之间的低级通讯,所以P.V为低级通讯原语。它只能传递简单的信号,不能传递交换大量信息,效率低 如果要在进程间传递大量信息则要用Send/Receive原语(高级通讯原语)2.6.1概述进程通信的方式共享存储器系统消息传递系统管道通信系统进程通信的方式共享存储器:1、共享数据结构如有界缓冲区,低效,适合于少量信息2、共享存储区相互通信的进程间设有公共内存,一组进程向该公共内存中写,另一组进程从公共内存中读,通过这种方式实现两组进程间的信息交换消息传递:系统为进程提供了两个高级通讯原语send和receivesend:

当要进行消息传递时执行sendreceive:

当接收者要接收消息时执行receive

按实现方式的不同,分为直接通信与间接通信。直接指将消息发送后,挂到接收进程的消息缓冲队列上,而间接则通过中间实体—信箱。共享文件模式:

管道通信,即pipe文件。写进程往里写数据,以字符流形式大量传送。读进程从管道中接收数据。管道—临界资源,利用管程来管理。管道通信必须提供以下几方面的能力:1、互斥2、同步3、对方是否存在。管

简单地说,管道就是连接一个程序的输出和另一个程序的输入的单向通道。

#ls–l|more这里建立了这样的一个管道:获取ls-l的输出,再将它作为more命令的输入。形象地说,就是数据沿着管道从左边流到了右边。

当进程创建一个管道的时候,系统内核同时为该进程设立了一对文件句柄(一个流),一个用来从该管道获取数据(read),另一个则用作管道的输出(write)。

#include<unistd.h>int

pipe(int

filedes[2]);返回:若成功则为0,若出错则为-1用C建立和使用管道

1.pipe函数

pipe函数用来建立管道。管道操作的情况主要有下面三种:(1)读管道:读操作按数据到达的顺序读取数据。(2)写管道:写入管道的数据按到达次序排列。

(3)管道的关闭:如果管道的读端口关闭,那么在该管道上的发出写操作调用的进程将接收到一个SIGPIPE信号。关闭写端口是给读端口一个文件结束符的惟一方法。对于写端口关闭后,在该管道上的read调用将返回0。单个进程中的管道几乎没有任何用处。通常,调用pipe的进程接着调用fork,这样就创建了从父进程到子进程或反之的IPC通道。fork之后做什么取决于我们想要有的数据流的方向。对于从父进程到子进程的管道,父进程关闭管道的读端(fd[0]),子进程则关闭写端(fd[1])。对于从子进程到父进程的管道,父进程关闭fd[1],子进程关闭fd[0]。当管道的一端被关闭后,下列规则起作用:当读一个写端已被关闭的管道时,在所有数据都被读取后,read返回0,以指示达到了文件结束处。如果写一个读端已被关闭的管道,则产生信号SIGPIPE。例#include "ourhdr.h"

intmain(void){ int n,fd[2];

pid_t

pid; char line[MAXLINE];

if(pipe(fd)<0) err_sys("pipeerror");

if((pid=fork())<0) err_sys("forkerror");elseif(pid>0){ /*parent*/ close(fd[0]); write(fd[1],"helloworld\n",12);

}else{ /*child*/ close(fd[1]); n=read(fd[0],line,MAXLINE); write(STDOUT_FILENO,line,n); }

exit(0);}消息传递模式消息缓冲在内存中开设缓冲区,发送进程将消息送入缓冲区,接收进程接收传递来的缓冲区信箱通信直接方式:发送进程发消息时要指定接收进程的名字,反过来,接收时要指明发送进程的名字

Send(receiver,message)

Receiver(sender,message)间接方式:发送进程发消息时不指定接收进程的名字,而是指定一个中间媒介,即信箱。进程间通过信箱实现通信

发送原语:send(MB,Message)

接收原语:receive(MB,Message)消息缓冲队列通信机制发送进程:申请消息缓冲区初始化消息缓冲区插入到接受进程消息缓冲队列接收进程:从消息队列摘下消息缓冲区取出消息归还资源消息缓冲区结构:

typemessagebuffer=record sender;发送者进程标识符

size;消息长度text;消息正文

next;指向下一个消息缓冲区的指针

end

proceduresend(receiver,a)begin

getbuf(a.size,i);根据a.size申请缓冲区;

i.sender∶=a.sender;将发送区a中的信息复制到消息缓冲区之中;

i.size∶=a.size;

i.text∶=a.text;

i.next∶=0;

getid(PCBset,receiver.j);获得接收进程内部标识符;

wait(j.mutex);

insert(j.mq,i);将消息缓冲区插入消息队列;

signal(j.mutex);

signal(j.sm);end3.接收原语接收原语描述如下:procedurereceive(b)beginj∶=internalname;j为接收进程内部的标识符;

wait(j.sm);

wait(j.mutex);

remove(j.mq,i);将消息队列中第一个消息移出;

signal(j.mutex);

b.sender∶=i.sender;将消息缓冲区i中的信息复制到接收区b;

b.size∶=i.size;

b.text∶=i.text;endLinux中通信消息队列、信号量、共享内存,统称为IPCIPC对象在内核中使用标识符,在程序中通过关键字引用构造关键字ftok();#include<sys/types.h>#include<sys/ipc.h>key_t

ftok(char*pathname,char

proj);例:key_t

mykey;mykey=ftok(".",’a’);共享内存(Linux)1、shmget():创建、获得一个共享存储区。系统调用格式:shmid=shmget(key,size,flag)其中,key是共享存储区的名字;size是其大小(以字节计);flag是用户设置的标志,如IPC_

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论