当前位置:文档之家› 实验三 进程管理

实验三 进程管理

实验三   进程管理
实验三   进程管理

实验三进程管理

一、目的

本课题实验的目的是,加深对进程概念及进程管理各个部分内容的理解;熟悉进程管理中主要数据结构的设计及进程调度算法,进程控制机构,同步机构,通信机构的实施。

二、题目

进程管理

三、要求及提示

1、要求设置PCB,进程控制原语,进程调度算法,能描述进程调度中不同进程状态

之间的转换,设计一个允许n个进程并发运行的进程管理模拟系统。该系统包括

有简单的进程控制,同步及通信机构,其进程调度算法可任意选择。每个进程用

一个PCB表示,其内容可根据具体情况设置。各进程之间应有一定的同步关系。

系统在运行过程中能显示或打印各进程的状态及有关参数的变化情况,以便观察

诸进程的运行过程及系统的管理过程。

2、编程实现。

3、工具:C语言或其它高级语言

4、实验时间:3学时

四、实验报告

1、写出进程管理的思想。

2、画出算法流程图和设置的数据结构。

3、写出调试程序出现的问题及解决的方法。

4、打印实验报告及程序清单。

5、报告给出测试的结果。

五、范例

支持多个进程并发运行的简单进程管理模拟系统。

1、问题描述

本系统的同步机构采用的是信号量上的P,V操作的机制;控制机构包括阻塞和唤醒操作;时间片中断处理程序处理模拟的时间片中断;进程调度程序负责为各进程分配处理机。系统中设计了3个并发进程。它们之间有如下同步关系:3个进程需要互斥使用临界资源s2,进程1和进程2又需互斥使用临界资源s1。本系统在运行过程中随机打印出各进程的状态变换过程,系统的调度过程及公共变量的变化情况。

2、算法

系统为进程设置了5种运行状态:e-执行态;r-高就绪态;t-低就绪态(执行进程因时间片到限而转入);w-等待态;c-完成态。各进程的初始状态均设置为r。系统分时执行各进程,并规定3个进程的执行概率均为33%。通过产生随机数x来模拟时间片。当进程process1访问随机数x时,若x ≥0.33;当进程process2访问x时,若x<0.33或x≥0.66;当进程process3访问x时,若x<0.66,分别认为各进程的执行时间片到限,产生“时间片中断”而转入低就绪态t。

进程调度算法采用剥夺式最高优先数法。各进程的优先数通过键盘输入予以静态设置。调度程序每次总是选择优先数最小(优先权最高)的就绪进程投入执行。

先从r状态进程中选择,在从t状态进程中选择。当现行进程唤醒某个等待进程,且被唤醒进程的优先数小于现行进程时,则剥夺现行进程的执行权。

各进程在使用临界资源s1和s2时,通过调用信号量sem1和sem2上的P,V操作来实现同步,阻塞和唤醒操作负责完成从进程的执行态到等待态到就绪态的转换。

系统启动后,在完成必要的系统初始化后便执行进程调度程序。但执行进程因“时间片中断”,或被排斥使用临界资源,或唤醒某个等待资源时,立即进行进程调度。当3个进程都处于完成状态后,系统退出运行。

图1和图2分别示出了系统主控程序和进程调度程序的大致流程。

图1 进程管理主控程序

3 、数据结构

(1)每个进程有一个进程控制块PCB,内容包括:

id 进程控制数,id=0,1,2;

status 进程状态,可为e,r,t,w,c;

priorty 进程优先数;

nexrtwr 等待链指针,只是在同一信号量上等待的下一个进程的标时数。(2)信号量semaphore,对于临界资源s1和s2分别有sem1和sem2均为互斥信号量。

内容包括:

value 信号量值,初值为1;

firstwr 等待链首指针,指示该信号量上等待的下一个进程标识数。

(3)现场保留区,用数组savearea[3][4]表示,即每一个进程都有一个大小为4个单元的保留区,用来保存被“中断”时的现场信息,如通用寄存器的内容和断点地址等。此外,系统中还用到下列主要全程变量:

exe 执行进程指针,其值为进程标识数;

i 用来模拟一个通用寄存器;

addr 用来模拟程序计数器;

s1,s2 两个公用变量,与来共享临界资源。

4、程序清单

#include

#define TRUE 1

#define FALSE 0

#define MAXPRI 100

#define NIL-1

struct{

int id;

char status;

int nextwr;

int priority;

}pcb[3];

struct{

int value;

int firstwr;

}sem[2];

char savearea[3][4],addr;

int i,s1,s2,seed,exe=NIL;

init() /*initialization*/

{ int j;

for (j=0;j<3;j++)

{

pcb[j].id=j;

pcb[j].status='r';

pcb[j].nextwr=NIL;

printf("\n process%d priority?",j+1);

scanf("%d",&i);

pcb[j].priority=i;

}

sem[0].value=1;sem[0].firstwr=NIL;

sem[1].value=1;sem[1].firstwr=NIL;

for(i=1;i<3;i++)

for(j=0;j<4;j++)

savearea[i][j]='0';

}

float random()

{int m;

if (seed<0)m=--seed;

else m=seed;

seed=(25173*seed+13849)%65536;

return(m/32767.0);

}

timeint(ad) /*time slice interrupt */

char ad;

{

float x;

x=random();

if((x<0.33)&&(exe==0))return(FALSE);

if((x<0.66)&&(exe==1))return(FALSE);

if((x<1.0)&&(exe==2))return(FALSE);

savearea[exe][0]=i;

savearea[exe][1]=ad;

pcb[exe].status='t';

printf("Time silce interrupt'\nprocess%d enter inro ready.\n",exe+1);

exe=NIL;

return(TRUE);

}

scheduler()

{int pd;

if((pd=find())==NIL&&exe==NIL)

return(NIL); /*quit system*/

if(pd!=NIL){

if(exe==NIL){

pcb[pd].status='e';

exe=pd;

printf("process%d is executing.\n",exe+1);

}

else if(pcb[pd].priority

{

pcb[exe].status='r';

printf("process%d enter into ready\n",exe+1);

pcb[pd].status='e';

exe=pd;

printf("process%d is executing\n",exe+1);

}

}

i=savearea[exe][0];

addr=savearea[exe][1];

return(exe);

}

find()

{ int j,pd=NIL,w=MAXPRI;

for (j=0;j<3;j++)

if(pcb[j].status=='r')

if (pcb[j].priority

w=pcb[j].priority;pd=j;

}

if (pd==NIL)

for (j=0;j<3;j++)

if(pcb[j].status=='t')

if(pcb[j].priority

w=pcb[j].priority;pd=j;

}

return (pd);

}

p(se,ad)

int se;

char ad;

{ if(--sem[se].value>=0) return(FALSE);

block(se);

savearea[exe][0]=i;

savearea[exe][1]=ad;

exe=NIL;

return(TRUE);

}

block(se)

int se;

{

int w;

printf("process%d is blocked\n",exe+1);

pcb[exe].status='w';

pcb[exe].nextwr=NIL;

if((w=sem[se].firstwr)==NIL)

sem[se].firstwr=exe;

else{

while(pcb[w].nextwr!=NIL)

w=pcb[w].nextwr;

pcb[w].nextwr=exe;

}

}

v(se,ad)

int se;

char ad;

{

if(++sem[se].value>0) return(FALSE);

wakeup(se);

savearea[exe][1]=ad;

savearea[exe][0]=i;

return (TRUE); /* scheduler*/

}

wakeup(se)

int se;

{

int w;

w=sem[se].firstwr;

if(w!=NIL){

sem[se].firstwr=pcb[w].nextwr;

pcb[w].status='r';

printf("process%d is waken up\n",w+1);

}

}

process1()

{

if(addr=='a')goto a1;

if(addr=='b')goto b1;

if(addr=='c')goto c1;

if(addr=='d')goto d1;

if(addr=='e')goto e1;

if(addr=='f')goto f1;

for(i=1;i<6;i++)

{

printf("process1 calls P on the semaphore 1\n");

if(p(0,'a')) break; /* process 1 is blocked*/

a1: printf("process1 is executing in the cretical section 1\n"); if(timeint('b')) break;

b1: printf("s1%d\n",++s1);

printf("process1 calls V on semaphore1 and quit cretical section

1.\n");

if(v(0,'c')) break;

c1: printf("process1 calls P on semaphore1 2.\n");

if(p(1,'d')) break;

d1: printf("process1 is executing cretical section 2.\n");

if(timeint ('e')) break;

e1: printf("s2=%d\n",++s2);

printf("process1 calls V on semephore2 and quit cretical section2.\n");

if(v(1,'f') )break;

f1: printf("process1 cycle count=%d\n",i);

}

if(i<6) return;

eexit(0);

}

process2()

{

if(addr=='a')goto a2;

if(addr=='b')goto b2;

if(addr=='c')goto c2;

if(addr=='d')goto d2;

if(addr=='e')goto e2;

if(addr=='f')goto f2;

for(i=1;i<6;++i)

{

printf("process2 calls Pon semephore2\n");

if(p(1,'a')) break;

a2: printf("process2 is executing on the cretical section2\n");

if(timeint('b')) break;

b2: printf("s2=%d\n",++s2);

printf("process2 calls V on semephore2 and quit cretical section2.\n"); if(v(1,'c')) break;

c2: printf("process2 calls P on semaphore1.\n");

if(p(0,'d')) break;

d2: printf("process2 is executing cretical section1.\n");

if(timeint('e')) break;

e2: printf("s1=%d\n",++s1);

printf("process2 calls V on semephore1 and quit cretical section1.\n"); if(v(0,'f')) break;

f2: printf("process2 cycle count=%d\n",i);

}

if(i<6) return;

eexit(1);

}

process3()

{

if(addr=='a')goto a3;

if(addr=='b')goto b3;

if(addr=='c')goto c3;

for(i=1;i<6;++i)

{

printf("process3 calls P on semaphore2\n");

if(p(1,'a')) break;

a3: printf("process3 is executing on the cretical section \n");

if(timeint('b')) break;

b3: printf("s2=%d\n",++s2);

printf("process3 calls V on semaphore2 and quit cretical section.\n"); if(v(1,'c')) break;

c3: printf("process3 cycle count=%d\n");

}

if(i<6) return;

eexit(2);

}

eexit(n)

int n;

{

pcb[n].status='c';

printf("process%d is completed !\n",n+1);

exe=NIL;

}

main()

{

int k;

printf("****process management*******\n\n");

init();

printf("s1=%d,s2=%d\n",s1,s2);

printf("process1,process2,process3 are all in ready1\n");

for( ; ;)

if((k=scheduler())!=NIL)

switch(k) {

case 0:process1();

break;

case 1:process2();

break;

case 2:process3();

break;

default:printf("process identifer error\n");

break;

}

else break;

printf("s1=%d,s2=%d\n",s1,s2);

printf("\n ******END*******\n");

}

windows进程管理实验报告

实验报告 课程名称:操作系统 实验项目:windows进程管理 姓名: 专业:计算机科学与技术 班级: 学号:

计算机科学与技术学院 计算机系 2019 年 4 月 23 日

实验项目名称: windows进程管理 一、实验目的 1. 学习windows系统提供的线程创建、线程撤销、线程同步等系统调用; 2. 利用C++实现线程创建、线程撤销、线程同步程序; 3. 完成思考、设计与练习。 二、实验用设备仪器及材料 1. Windows 7或10, VS2010及以上版本。 三、实验内容 1 线程创建与撤销 写一个windows控制台程序(需要MFC),创建子线程,显示Hello, This is a Thread. 然后撤销该线程。 相关系统调用: 线程创建: CreateThread() 线程撤销: ExitThread() 线程终止: ExitThread(0) 线程挂起: Sleep() 关闭句柄: CloseHandle() 参考代码: ; } 运行结果如图所示。 完成以下设计题目: 1. 向线程对应的函数传递参数,如字符串“hello world!”,在线程中显示。 2. 如何创建3个线程A, B, C,并建立先后序执行关系A→B→C。

实验内容2 线程同步 完成父线程和子线程的同步。父线程创建子线程后进入阻塞状态,子线程运行完毕后再唤醒。 相关系统调用: 等待对象 WaitForSingleObject(), WaitForMultipleObjects(); 信号量对象 CreateSemaphore(), OpenSemaphore(), ReleaseSemaphore(); HANDLE WINAPI CreateSemaphore( _In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes _In_ LONG lInitialCount, _In_ LONG lMaximumCount, _In_opt_ LPCTSTR lpName ); 第一个参数:安全属性,如果为NULL则是默认安全属性 第二个参数:信号量的初始值,要>=0且<=第三个参数 第三个参数:信号量的最大值 第四个参数:信号量的名称 返回值:指向信号量的句柄,如果创建的信号量和已有的信号量重名,那么返回已经存在的信号量句柄参考代码: n"); rc=ReleaseSemaphore(hHandle1,1,NULL); err=GetLastError(); printf("Release Semaphore err=%d\n",err); if(rc==0) printf("Semaphore Release Fail.\n"); else printf("Semaphore Release Success. rc=%d\n",rc); } 编译运行,结果如图所示。

操作系统实验报告--实验一--进程管理

实验一进程管理 一、目的 进程调度是处理机管理的核心内容。本实验要求编写和调试一个简单的进程调度程序。通过本实验加深理解有关进程控制块、进程队列的概念,并体会和了解进程调度算法的具体实施办法。 二、实验内容及要求 1、设计进程控制块PCB的结构(PCB结构通常包括以下信息:进程名(进程ID)、进程优先数、轮转时间片、进程所占用的CPU时间、进程的状态、当前队列指针等。可根据实验的不同,PCB结构的内容可以作适当的增删)。为了便于处理,程序中的某进程运行时间以时间片为单位计算。各进程的轮转时间数以及进程需运行的时间片数的初始值均由用户给定。 2、系统资源(r1…r w),共有w类,每类数目为r1…r w。随机产生n进程P i(id,s(j,k),t),0<=i<=n,0<=j<=m,0<=k<=dt为总运行时间,在运行过程中,会随机申请新的资源。 3、每个进程可有三个状态(即就绪状态W、运行状态R、等待或阻塞状态B),并假设初始状态为就绪状态。建立进程就绪队列。 4、编制进程调度算法:时间片轮转调度算法 本程序用该算法对n个进程进行调度,进程每执行一次,CPU时间片数加1,进程还需要的时间片数减1。在调度算法中,采用固定时间片(即:每执行一次进程,该进程的执行时间片数为已执行了1个单位),这时,CPU时间片数加1,进程还需要的时间片数减1,并排列到就绪队列的尾上。 三、实验环境 操作系统环境:Windows系统。 编程语言:C#。 四、实验思路和设计 1、程序流程图

2、主要程序代码 //PCB结构体 struct pcb { public int id; //进程ID public int ra; //所需资源A的数量 public int rb; //所需资源B的数量 public int rc; //所需资源C的数量 public int ntime; //所需的时间片个数 public int rtime; //已经运行的时间片个数 public char state; //进程状态,W(等待)、R(运行)、B(阻塞) //public int next; } ArrayList hready = new ArrayList(); ArrayList hblock = new ArrayList(); Random random = new Random(); //ArrayList p = new ArrayList(); int m, n, r, a,a1, b,b1, c,c1, h = 0, i = 1, time1Inteval;//m为要模拟的进程个数,n为初始化进程个数 //r为可随机产生的进程数(r=m-n) //a,b,c分别为A,B,C三类资源的总量 //i为进城计数,i=1…n //h为运行的时间片次数,time1Inteval为时间片大小(毫秒) //对进程进行初始化,建立就绪数组、阻塞数组。 public void input()//对进程进行初始化,建立就绪队列、阻塞队列 { m = int.Parse(textBox4.Text); n = int.Parse(textBox5.Text); a = int.Parse(textBox6.Text); b = int.Parse(textBox7.Text); c = int.Parse(textBox8.Text); a1 = a; b1 = b; c1 = c; r = m - n; time1Inteval = int.Parse(textBox9.Text); timer1.Interval = time1Inteval; for (i = 1; i <= n; i++) { pcb jincheng = new pcb(); jincheng.id = i; jincheng.ra = (random.Next(a) + 1); jincheng.rb = (random.Next(b) + 1); jincheng.rc = (random.Next(c) + 1); jincheng.ntime = (random.Next(1, 5)); jincheng.rtime = 0;

进程管理实验报告

实验2过程管理实验报告学生号姓名班级电气工程系过程、过程控制块等基本原理过程的含义:过程是程序运行过程中对数据集的处理,以及由独立单元对系统资源的分配和调度。在不同的数据集上运行程序,甚至在同一数据集上运行多个程序,是一个不同的过程。(2)程序状态:一般来说,一个程序必须有三种基本状态:就绪、执行和阻塞。然而,在许多系统中,过程的状态变化可以更好地描述,并且增加了两种状态:新状态和终端状态。1)就绪状态,当一个进程被分配了除处理器(CPU)以外的所有必要资源时,只要获得了处理器,进程就可以立即执行。此时,进程状态称为就绪状态。在系统中,多个进程可以同时处于就绪状态。通常,这些就绪进程被安排在一个或多个队列中,这些队列称为就绪队列。2)一旦处于就绪状态的进程得到处理器,它就可以运行了。进程的状态称为执行状态。在单处理器系统中,只有一个进程在执行。在多处理器系统中,可能有多个进程在执行中。3)阻塞状态由于某些事件(如请求输入和输出、额外空间等),执行进程被挂起。这称为阻塞状态,也称为等待状态。通常,处于阻塞状态的进程被调度为-?这个队列称为阻塞队列。4)新状态当一个新进程刚刚建立并且还没有放入就绪队列中时,它被称为新状态。5)终止状态是

什么时候-?进程已正常或异常终止,操作系统已将其从系统队列中删除,但尚未取消。这就是所谓的终结状态。(3)过程控制块是过程实体的重要组成部分,是操作系统中最重要的记录数据。控制块PCB记录操作系统描述过程和控制过程操作所需的所有信息。通过PCB,一个不能独立运行的程序可以成为一个可以独立运行的基本单元,并且可以同时执行一个进程。换句话说,在进程的整个生命周期中,操作系统通过进程PCB管理和控制并发进程。过程控制块是系统用于过程控制的数据结构。系统根据进程的PCB来检测进程是否存在。因此,进程控制块是进程存在的唯一标志。当系统创建一个进程时,它需要为它创建一个PCB;当进程结束时,系统回收其PCB,进程结束。过程控制块的内容过程控制块主要包括以下四个方面的信息。过程标识信息过程标识用于对过程进行标识,通常有外部标识和内部标识。外部标识符由流程的创建者命名。通常是一串字母和数字。当用户访问进程时使用。外部标识符很容易记住。内部标识符是为了方便系统而设置的。操作系统为每个进程分配一个唯一的整数作为内部标识符。通常是进程的序列号。描述性信息(process scheduling message)描述性信息是与流程调度相关的一些有关流程状态的信息,包括以下几个方面。流程状态:表

进程管理实验报告

进程的控制 1 .实验目的 通过进程的创建、撤消和运行加深对进程概念和进程并发执行的理解,明确进程与程序之间的区别。 【答:进程概念和程序概念最大的不同之处在于: (1)进程是动态的,而程序是静态的。 (2)进程有一定的生命期,而程序是指令的集合,本身无“运动”的含义。没有建立进程的程序不能作为1个独立单位得到操作系统的认可。 (3)1个程序可以对应多个进程,但1个进程只能对应1个程序。进程和程序的关系犹如演出和剧本的关系。 (4)进程和程序的组成不同。从静态角度看,进程由程序、数据和进程控制块(PCB)三部分组成。而程序是一组有序的指令集合。】2 .实验内容 (1) 了解系统调用fork()、execvp()和wait()的功能和实现过程。 (2) 编写一段程序,使用系统调用fork()来创建两个子进程,并由父进程重复显示字符串“parent:”和自己的标识数,而子进程则重复显示字符串“child:”和自己的标识数。 (3) 编写一段程序,使用系统调用fork()来创建一个子进程。子进程通过系统调用execvp()更换自己的执行代码,新的代码显示“new

program.”。而父进程则调用wait()等待子进程结束,并在子进程结束后显示子进程的标识符,然后正常结束。 3 .实验步骤 (1)gedit创建进程1.c (2)使用gcc 1.c -o 1编译并./1运行程序1.c #include #include #include #include void mian(){ int id; if(fork()==0) {printf(“child id is %d\n”,getpid()); } else if(fork()==0) {printf(“child2 id %d\n”,getpid()); } else {id=wait(); printf(“parent id is %d\n”,getpid()); }

操作系统进程管理系统设计实验报告

实验报告说明书设计名称:操作系统课程设计 实验:进程调度设计 学生姓名: 专业:网络工程 班级: 08级一班 学号: 指导教师:雷晓平王东黄营杨跃武 日期: 2011年 6月 19日

课程设计任务书 网络工程专业 08 年级 1 班 一、具体要求 本课程设计共2周,采取集中方式。 ㈠主要设计内容 1、进程调度 2、存储管理 3、文件管理 ㈡操作系统分项设计 1、设计一:进程管理系统设计 目的与要求:本设计的目的是加深对进程概念及进程管理各部分内容的理解;熟悉进程管理中主要数据结构的设计及进程调度算法、进程控制机构、同步机构及通讯机构的实施。 要求设计一个允许n个进程并发运行的进程管理模拟系统。该系统包括有简单的进程控制、同步与通讯机构,其进程调度算法可任意选择。每个进程用一个PCB表示,其内容根据具体情况设置。各进程之间有一定的同步关系(可选)。系统在运行过程中应能显示或打印各进程的状态及有关参数的变化情况,以便观察诸进程的运行过程及系统的管理过程。 具体详见:设计任务书1--进程调度算法.doc 2、设计二:存贮器管理系统设计 目的与要求:本设计的目的是使学生熟悉存贮器管理系统的设计方法;加深对所学各种存贮器管理方案的了解;要求采用一些常用的存贮器分配算法,设计一个存贮器管理模拟系统并调试运行。模拟环境应尽量接近真实。 具体详见:设计任务书2--内存分区管理模拟.doc 3、设计三:虚拟存储器管理系统设计 本设计的目的是通过设计一个简单的虚拟存储器管理系统来模拟实际的页面调度算法与过程,以掌握这种有用的技术。要求将其输入/输出处理程序编成一个独立的进程模块并与其它请求输入/输出的进程并发运行。并要求加入设备管理子模块。 具体分析为:页面调度算法主要有FIFO、最近最少使用调度算法(LRU)、最近最不常用调度算法(LFU)、最佳算法(OPT)等。题目要求: ①实现三种算法:1、先进先出;2、OPT;3、LRU ②页面序列从指定的文本文件(TXT文件)中取出 ③输出:第一行:每次淘汰的页面号,第二行:显示缺页的总次数 4、设计四:文件管理系统设计 目的与要求:本设计的目的是通过设计和调试一个简单的外部文件系统,主要是模拟文件操作,,使学生对主要文件操作命令的实质和执行过程有比较深入的了解,掌握它们的基本实施方法。 基本要求如下: 实现三种算法:先来先服务、最短寻道优先、电梯算法 磁道服务顺序从指定的文本文件(TXT文件)中取出 输出:第一行:磁道的服务顺序;第二行:显示移动总道数

操作系统-进程管理实验报告

实验一进程管理 1.实验目的: (1)加深对进程概念的理解,明确进程和程序的区别; (2)进一步认识并发执行的实质; (3)分析进程争用资源的现象,学习解决进程互斥的方法; (4)了解Linux系统中进程通信的基本原理。 2.实验预备内容 (1)阅读Linux的sched.h源码文件,加深对进程管理概念的理解; (2)阅读Linux的fork()源码文件,分析进程的创建过程。 3.实验内容 (1)进程的创建: 编写一段程序,使用系统调用fork() 创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”,子进程分别显示字符“b”和“c”。试观察记录屏幕上的显示结果,并分析原因。 源代码如下: #include #include #include #include #include int main(int argc,char* argv[]) { pid_t pid1,pid2; pid1 = fork(); if(pid1<0){ fprintf(stderr,"childprocess1 failed"); exit(-1); } else if(pid1 == 0){ printf("b\n"); } 1/11

else{ pid2 = fork(); if(pid2<0){ fprintf(stderr,"childprocess1 failed"); exit(-1); } else if(pid2 == 0){ printf("c\n"); } else{ printf("a\n"); sleep(2); exit(0); } } return 0; } 结果如下: 分析原因: pid=fork(); 操作系统创建一个新的进程(子进程),并且在进程表中相应为它建立一个新的表项。新进程和原有进程的可执行程序是同一个程序;上下文和数据,绝大部分就是原进程(父进程)的拷贝,但它们是两个相互独立的进程!因此,这三个进程哪个先执行,哪个后执行,完全取决于操作系统的调度,没有固定的顺序。 (2)进程的控制 修改已经编写的程序,将每个进程输出一个字符改为每个进程输出一句话,再观察程序执行时屏幕上出现的现象,并分析原因。 将父进程的输出改为father process completed 2/11

进程管理器的模拟实现

衡阳师范学院《操作系统》课程设计 题目:进程管理器的模拟实现系别:计算机科学系 专业:物联网工程 班级:1206班 学生姓名:郑晓娟 学号:12450218 指导老师:王玉奇 完成日期:2014年12月28日

目录 一、需求分析 (3) 二、概要设计 (3) 三、详细设计 (4) 1.进程PCB结构体的定义 (4) 2.创建模块 (4) 3.查看模块 (5) 4.换出模块 (6) 5.杀死模块 (8) 四、程序调试 (10) 五、总结分析 (14)

一、需求分析 有时候我们需要去了解我们电脑的运行情况,掌握和管理它的进程,并对其异常情况给予操作和控制。进程管理器就像我们了解和控制自己电脑运作的一个窗口,通过这个窗口我们可以查看到所有进程的运行情况,并对运行的进程加以管理和控制。在本课程设计中,进入模拟进程系统后,可以根据请求选择“创建进程”创建新的进程。还可以选择“查看进程“来查看当前正在运行的进程,以及该进程的相关的信息,其中包括进程的pid,进程优先级,进程大小和进程的内容,我们可以通过这些来了解计算机中每个进程的使用状况。选择“换出进程”,可以挂起某个正在运行的进程。选择“撤销进程”,可以停止某个正在运行的程序,并且释放其占用的资源。选择“退出进程”,可以退出进程模拟系统。 二、概要设计 程序流程:

三、详细设计 (1)进程PCB结构体的定义 struct jincheng_type{ //定义表示进程信息的结构体int pid; //进程ID int youxian; //优先级 int daxiao; //大小 int zhuangtai; //进程的状态,这里用0表示没有建立或被杀死,1表示执行,2表示换出 int neirong; //内容 }; (2)创建模块 void create() //函数--创建一个新进程 { if(shumu>=20) printf("\n内存已满,请先换出或杀死进程\n") //判断内存空间是否已满 else{ for(int i=0;i<20;i++) if(neicun[i].zhuangtai==0) break; //选出空着的内存单元给新进程使用 printf("\n请输入新进程pid\n"); //输入新进程ID存至选出的内存单元 scanf("%d",&(neicun[i].pid));

进程管理_实验报告一流程图

实验一 课程名称:操作系统 课程类型:必修 实验项目名称:进程管理 实验题目:短作业优先算法、动态可剥夺优先数算法和基本循环轮转算法。 一、实验目的 进程是操作系统最重要的概念之一,进程调度又是操作系统核心的主要内容。本实验要求学生独立的用高级语言编写和调试一个简单的模拟进程调度的程序。通过本实验,加深学生理解有关进程控制块、进程队列的概念,并体会和了解短作业优先、优先数和时间片轮转调度算法的具体实施办法。 二、实验要求及实验环境 (1)设计一个有n 个进程的进程调度程序(具体个数可由键盘输入)。每一个进程用一个进程控制块PCB 来代表。PCB 中应包含下列信息:进程名、进程优先数、进程的状态、进程需要运行的时间及利用CPU运行的时间等。进程的个数、各进程的优先数、轮转时间片数以及进程运行需要地时间可由

键盘输入。 (2)调度程序应包含2~3 种不同的调度算法,运行时可任选一种。 (3)每个进程处于运行Run、就绪ready 和完成Finish 三种状态之一,假定初始状态都为就绪状态ready。(也可没有Finish状态,可以在设计程序时实现处以Finish状态的进程删掉)。 (4)系统能显示各进程状态和参数的变化情况。(5)动态可剥夺优先数算法是:在创建进程时给定一个初始的优先数,当进程获得一次cpu后其优先数就减少1,如果就绪队列中有优先级更高的将剥夺运行中的进程。 三、设计思想 (本程序中的用到的所有数据类型的定义,主程序的流程图及各程序模块之间的调用关系) 1.程序流程图 (见下图) 2.逻辑设计 使用链表表示就绪队列,每个元素包括进程名、进程优先数、进程的状态、进程需要运行的时间及利用CPU运行的时间等信息。 该结构需支持以下操作:取头节点,在表尾插入节

进程管理模拟实验指导书09

进程管理模拟系统实验指导书2 一、实验目的 学习进程管理的设计与实现,学习和运用操作系统原理,设计一个操作系统子系统的模拟系统。通过该系统的设计调试可增加对操作系统实现的感知性。同时可发挥团队协作精神和个人创造能力。使同学们对操作系统学习有一个实现的尝试和创新的思维。 二、实验规则 1.每组设计一个模拟系统(共100分) 2.每人设计系统中的一部分(满分60分) 3.集体调试创意(满分40分) 三、实验要求 1.进程管理功能以进程调度为主要功能。以进程控制为辅助功能。 2.体现操作系统原理中进程调度算法和进程控制算法。按照操作系统原理设计。 3.结构化设计。设计时构建出模块结构图并存于文件中。模块化实现,对每一功能,每一操作使用模块、函数、子程序设计方法实现。 4.进程以PCB为代表。队列、指针用图示。每一步功能在桌面上能显示出来。 5.系统应具有排错功能,对可能出现的错误应具有排查功能和纠错能力。 6.界面自行设计,语言自行选择。(可用VC/C++/C/C#语言,也可用你会的其他语言,甚至还可用PPT) 7.每人的设计功能都能表现或说明出来。 8.进程以队列法组织,对不同进程调度算法: FIFO队列或PRI队列或rotate(轮转队列)用同一个进程序列组织,对阻塞队列可设置一个,也可设多个。 9.因为是模拟系统,所以要显示每个功能和操作结果。显示应力求清晰、易读和一目了然(一屏),最好能用汉字,否则可用英语或汉语拼音。 10.操作方便,使用便捷。可视化程度高。 11.设计出系统后,还需要写出(介绍系统采用的语言、支撑平台、小组成员及分工。如何安装、如何启动、如何操作) 12.每组需写一份课程设计报告,内容包括:课程设计内容,课程设计设计思路,课程设计结构图,及分工内容、介绍。 13. 实验结果演示验收后,将可在任何环境下运行的可执行文件和系统说明书一起存盘并交盘。(可合组一张盘),上标:班级、组号、姓名。 14. 实验结束后从中选出优秀作品,介绍给大家。 四、系统功能 1.创建进程:主要创建PCB,并在创建后显示PCB及所在RL队列。内容包括①标识数(按产生顺序产生),②进程名(字母序列),③优先数(随机产生),④进程状态,⑤队列指针(可用数字或图表示),⑥其它(可自定义:如运行时间、家族等)。创建进程的个数可人工设定,或可自动设定,也可两者兼有。 2.撤销进程:撤销进程主要显示PCB的消失和队列的变化。 3.进程队列的组织:进程队列可对创建的所有进程变化队形:可组织成FIFO队列,也可组织成PRI队列;或rotate队列,对队列有插入、移出的功能,也有在队列中某位置插入删除功能。 4.显示功能:模拟系统在整个演示过程中都需要可视化,因此显示功能非常重要,要求对队列、PCB每次操作前后予以显示,以表示操作功能的实施效果。

进程管理系统设计

目录 一、设计系统目的 (1) (1) 三、系统分析 (1) 四、系统设计 (1) 五、程序设计流程图 (5) 六、源程序清单 (5) 七、调试过程中的问题及系统测试情况 (12) 1 (12) 2、系统测试结果 (12) 八、系统设计总结 (14)

一、设计系统目的 本设计的目的是加深对进程概念及进程管理各部分内容的理解,熟悉进程管理中主要数据结构的设计及进程调度算法、进程控制机构、同步机构及通讯机构实施。 设计一个允许n个进程并发运行的进程管理模拟系统。该系统包括有简单的进程控制、同步与通讯机构,其进程调度算法可任意选择。每个进程用一个PCB表示,其内容根据具体情况设置。各进程之间有一定的同步关系可选。系统在运行过程中应能显示或打印各进程的状态及有关参数的变化情况,以便观察诸进程的运行过程及系统的管理过程。 三、系统分析 1、进程控制和同步等 可以控制进程的就绪执行和阻塞三种状态等基本功能。 2、进程调度 调度算法采用的是先来先服务算法。 3 输出的内容包括—就绪的进程队列,当前cup正在执行的进程,被阻塞的进程队 列。 四、系统设计 本系统所包括的数据结构是对列类 本系统由于需要输出就绪队列,执行队列,阻塞对列,故需要利用对列来实现。 最好利用队列类来实现,这样可以充分利用类的继承来简化程序。 class queue { public:

queue():rear(NULL),front(NULL){}; ~queue(); void enqueue( char &item); char dequeue(); void del(char item); void display(); int find(char item); int isempty(){return front==NULL;} private: queuenode *front,*rear; }; queue::~queue() { queuenode * p; while(front!=NULL) { p=front;front=front->link;delete p; } 队列类的成员函数的定义如下: void queue::enqueue(char &item) { if(front==NULL) front=rear=new queuenode(item,NULL); else rear=rear->link=new queuenode(item,NULL); } char queue::dequeue() {

进程管理实验报告

进程管理实验报告 1 .实验目的 通过进程的创建、撤消和运行加深对进程概念和进程并发执行的理解,明确进程与程序之间的区别。 【答:进程概念和程序概念最大的不同之处在于: (1)进程是动态的,而程序是静态的。 (2)进程有一定的生命期,而程序是指令的集合,本身无“运动”的含义。没有建立进程的程序不能作为1个独立单位得到操作系统的认可。 (3)1个程序可以对应多个进程,但1个进程只能对应1个程序。进程和程序的关系犹如演出和剧本的关系。 (4)进程和程序的组成不同。从静态角度看,进程由程序、数据和进程控制块(PCB)三部分组成。而程序是一组有序的指令集合。】2 .实验内容 (1) 了解系统调用fork()、execvp()和wait()的功能和实现过程。 (2) 编写一段程序,使用系统调用fork()来创建两个子进程,并由父进程重复显示字符串“parent:”和自己的标识数,而子进程则重复显示字符串“child:”和自己的标识数。 (3) 编写一段程序,使用系统调用fork()来创建一个子进程。子进程通过系统调用execvp()更换自己的执行代码,新的代码显示“new program.”。而父进程则调用wait()等待子进程结束,并在子进程结束后显示子进程的标识符,然后正常结束。

(3)运行并查看结果 child’s pid=2894 child’s pid=2994 parent’s pid=2849 child’s pid=2897 child’s pid=2897 parent’s pid=2849 child’s pid=2894 child’s pid=2994 parent’s pid=2849 (4)gedit创建进程2.c 使用gcc 2.c -o 2编译并./2运行程序2.c#include #include #include #include #include(6)运行并查看结果 new program ! -rw-r–r--. 1 root root 2456 Apr 14 2019 /etc/passwd child peocess PID:29035 4 .思考 (1) 系统调用fork()是如何创建进程的?

操作系统-实验三-进程管理-实验报告

计算机与信息工程学院实验报告 一、实验内容 1.练习在shell环境下编译执行程序 (注意:①在vi编辑器中编写名为sample.c的c语言源程序 ②用linux自带的编译器gcc编译程序,例如:gcc –o test sample.c ③编译后生成名为test.out的可执行文件; ④最后执行分析结果;命令为:./test) 注意:linux自带的编译程序gcc的语法是:gcc –o 目标程序名源程序名,例如:gcc –o sample1 sample1.c,然后利用命令:./sample 来执行。如果仅用“gcc 源程序名”,将会把任何名字的源程序都编译成名为a.out的目标程序,这样新编译的程序会覆盖原来的程序,所以最好给每个源程序都起个新目标程序名。 2.进程的创建 仿照例子自己编写一段程序,使用系统调用fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示“a”,子进程分别显示字符“b”和“c”。观察记录屏幕上的显示结果,并分析原因。 3.分析程序 实验内容要在给出的例子程序基础上,根据要求进行修改,对执行结果进行分析。二、

实验步骤 1. 利用fork()创建一个小程序 (1)编写程序 #include main () { int i=5; pid_t pid; pid=fork(); for(;i>0;i--) { if (pid < 0) printf("error in fork!"); else if (pid == 0) printf("i am the child process, my process id is %d and i=%d\n",getpid(),i); else printf("i am the parent process, my process id is %d and i=%d\n",getpid(),i); } for(i=5;i>0;i--) { if (pid < 0) printf("error in fork!"); else if (pid == 0) printf("the child process, my process id is %d and i=%d\n",getpid(),i); else printf("the parent process, my process id is %d and

操作系统课程设计(进程管理)

操作系统课程设计报告 题目: 专业: 班级: 姓名: 学号: 指导老师: 年月日

《操作系统》课程设计任务书 一、课程设计题目(任选一个题目) 1.模拟进程管理 2.模拟处理机调度 3.模拟存储器管理 4.模拟文件系统 5.模拟磁盘调度 二、设计目的和要求 1.设计目的 《操作系统原理》课程设计是计算机科学与技术专业实践性环节之一,是学习完《操作系统原理》课程后进行的一次较全面的综合练习。其目的在于加深对操作系统的理论、方法和基础知识的理解,掌握操作系统结构、实现机理和各种典型算法,系统地了解操作系统的设计和实现思路,培养学生的系统设计能力,并了解操作系统的发展动向和趋势。 2.基本要求: (1)选择课程设计题目中的一个课题,独立完成。 (2)良好的沟通和合作能力 (3)充分运用前序课所学的软件工程、程序设计、数据结构等相关知识 (4)充分运用调试和排错技术 (5)简单测试驱动模块和桩模块的编写 (6)查阅相关资料,自学具体课题中涉及到的新知识。 (7)课题完成后必须按要求提交课程设计报告,格式规范,内容详实。 三、设计内容及步骤 1.根据设计题目的要求,充分地分析和理解问题,明确问题要求做什么。

2.根据实现的功能,划分出合理的模块,明确模块间的关系。 3.编程实现所设计的模块。 4.程序调试与测试。采用自底向上,分模块进行,即先调试低层函数。能够熟练掌握调试工具的各种功能,设计测试数据确定疑点,通过修改程序来证实它或绕过它。调试正确后,认真整理源程序及其注释,形成格式和风格良好的源程序清单和结果; 5.结果分析。程序运行结果包括正确的输入及其输出结果和含有错误的输入及其输出结果。 6.编写课程设计报告; 设计报告和实验报告要求:A4纸和实验报告册,详细设计部分主要叙述本人的工作内容 设计报告的格式: (1)封面(题目、指导教师、专业、班级、姓名、学号) (2)设计任务书 (3)目录 (4)需求分析 (5)概要设计 (6)详细设计(含主要代码) (7)调试分析、测试结果 (8)用户使用说明 (9)附录或参考资料 四、进度安排 设计在第四学期的第1-18周(共18课时)进行,时间安排如下:

实验一、进程调度实验报告

实验一、进程调度实验报告

广东技术师范学院实验报告 学院:计算机科学学 院 专业: 计算机科学与 技术(师范) 班级:成绩: 姓名:学号:组别:组员: 实验地点:实验日期:指导教师签名: 实验名称:实验一、进程调度实验 一、实验目的 用高级语言编写和调试一个进程调度程序,以加深对进程的概念及进程调度算法的理解 二、实验类别 综合性实验。综合高级语言编程、进程调度模型、进程调度算法及数据结构等多方面的知识 三、实验内容和步骤 1.编写并调试一个模拟的进程调度程序,采用“最高优先数优先”调度算法对五个进程进行调度。 “最高优先数优先”调度算法的基本思想是把CPU分配给就绪队列中优先数最高的进程。 静态优先数是在创建进程时确定的,并在整个进程运行期间不再改变。 动态优先数是指进程的优先数在创建进程时可以给定一个初始值,并且可以按一定原则修改优先数。例如:在进程获得一次CPU后就将其优先数减少1。或者,进程等待的时间超过某一时限时增加其优先数的值,等等 该题根据老师给的代码用Visual C++运行,结果以及分析如下: 预习情况操作情况考勤情况数据处理情况

结果分析:根据上述输入的三个进程的信息可以得到:优先级最高的是进程cc 最先调度进程cc的状态为运行态,需要执行的时间为10当前就绪队列状态为:进程aa先级比较高,处于就绪队列前面,而进程bb先级是三者中最低的,所以处于就绪队列的最后。而此时这两个进程的状态都为就绪态。

结果分析:当进程cc了一个时间片之后而它已占用CPU时间已达到所需要的运行时间,则将它的优先级减1之后,再将三个进程按优先级的大小排列,从中选择优先级大的进程进入运行状态,则该次进入运行态的是进程aa 按照这种方式一直运行下去: 直到:

模拟进程管理

操作系统课程设计报告 院系:计算机科学技术 班级:计092班 姓名:杨志 学号:17 号 指导教师:鲁静轩__________ 2011 年12 月10 日

操作系统课程设计任务书 一、设计题目:模拟进程管理 二、设计目的 《操作系统原理》课程设计是软件工程专业实践性环节之一,是学习完《操作系统原理》课程后进行的一次较全面的综合练习。其目的在于加深对操作系统的理论、方法和基础知识的理解,掌握操作系统结构、实现机理和各种典型算法,系统地了解操作系统的设计和实现思路,培养学生的系统设计能力,并了解操作系统的发展动向和趋势。 三、设计要求 (1)选择课程设计题目中的一个课题,独立完成。 (2)良好的沟通和合作能力 (3)充分运用前序课所学的软件工程、程序设计等相关知识 (4)充分运用调试和排错技术 (5)简单测试驱动模块和桩模块的编写 (6)查阅相关资料,自学具体课题中涉及到的新知识。 (7)课题完成后必须按要求提交课程设计报告,格式规范,内容详实。 四、设计内容 1.根据设计题目的要求,充分地分析和理解问题,明确问题要求做什么。 2.根据实现的功能,划分出合理的模块,明确模块间的关系。 3.编程实现所设计的模块。 4.程序调试与测试。采用自底向上,分模块进行,即先调试低层函数。能够熟练掌握调试工具的各种功能,设计测试数据确定疑点,通过修改程序来证实它或绕过它。调试正确后,认真整理源程序及其注释,形成格式和风格良好的源程序清单和结果; 5.结果分析。程序运行结果包括正确的输入及其输出结果和含有错误的输入及其输出结果。 6.编写课程设计报告; 设计报告要求:A4纸,详细设计部分主要叙述本人的工作内容 设计报告的格式: (1)封面(题目、指导教师、专业、班级、姓名、学号) (2)设计任务书 (3)目录 (4)需求分析 (5)概要设计 (6)详细设计(含主要代码) (7)调试分析、测试结果 (8)用户使用说明 (9)附录或参考资料

实验1_进程管理

实验一进程管理 【实验目的】 1.加深对进程概念及进程管理各部分内容的理解。 2.熟悉进程管理中主要数据结构的设计和进程调度算法、进程控制机构、同步机构、通讯机构的实施。 【实验要求】 1.调试并运行一个允许n 个进程并发运行的进程管理模拟系统。了解该系统的进程控制、同 2.步及通讯机构,每个进程如何用一个PCB 表示、其内容的设置;各进程间的同步关系;系统在运行过程中显示各进程的状态和有关参数变化情况的意义。 【实验环境】 具备Windows或MS-DOS操作系统、带有Turbo C 集成环境的PC机。 【实验重点及难点】 重点:理解进程的概念,进程管理中主要数据结构的设计和进程调度算法、进程控制 机构、同步机构、通讯机构的实施。 难点:实验程序的问题描述、实现算法、数据结构。 【实验内容】 一.阅读实验程序 程序代码见【实验例程】。 二.编译实验例程 用Turbo C 编译实验例程。 三.运行程序并对照实验源程序阅读理解实验输出结果的意义。 【问题与讨论】 系统为进程设置了几种状态?说明这些状态的含义。 三种。就绪、执行、阻塞。就绪:处于就绪状态的进程已经得到除 CPU之外的其他资源,只要由调度得到处理机,便可立即投入执行。执行:只有处于内存就绪状态的进程在得到处理机后才能立即投入执行。阻塞:进程因等待某个事件发生而放弃处理机进入等待状态。 采用何种方式来模拟时间片?简要说明实现方法。 系统分时执行各进程,并规定3个进程的执行概率均为33%。通过产生随机数x来模拟时间片。当进程process1访问随机数x时,若x ≥0.33;当进程process2访问x时,若x<0.33或x≥0.66;当进程process3访问x时,若x<0.66,分别认为各进程的执行时间片到限,产生“时间片中断”而转入低就绪态t。 进程调度算法采用剥夺式最高优先数法。各进程的优先数通过键盘输入予以静态设置。调度程序每次总是选择优先数最小(优先权最高)的就绪进程投入执行。先从r状态进程中选择,在从t状态进程中选择。当现行进程唤醒某个等待进程,且被唤醒进程的优先数小于现行进程时,则剥夺现行进程的执行权。 各进程在使用临界资源s1和s2时,通过调用信号量sem1和sem2上的P,V操作来实现同步,阻塞和唤醒操作负责完成从进程的执行态到等待态到就绪态的转换。 系统启动后,在完成必要的系统初始化后便执行进程调度程序。但执行进程因“时间片中断”,或被排斥使用临界资源,或唤醒某个等待资源时,立即进行进程调度。当3个进程都处于完成状态后,系统退出运行 由于输出结果较多,一屏显示不完,如何较好地阅读程序输出? 一是在程序中控制输出的行数,比如20行,输出后用gets停顿一下,继续时回车即可;

进程管理实验报告

实验报告纸 (院、系)专业班组课 实验一、进程管理(3学时、必做) 一、实验目的 通过实验使学生进一步了解进程、进程状态、进程控制等基本概念。基本能达到下列具体的目标: 1、理解进程PCB 的概念,以及PCB 如何实现、如何组织以及管理。 2、复习数据结构中如何对链的操作,包括建链、删除、插入结点等,来实现进程的管 理。 二、实验内容 1、建立一个结点,即PCB 块包括用户标识域、状态域(执行、等待、就绪)、link 域。 2、建立三个队列(执行队列、就绪队列、等待队列)。 3、根据进程状态转换实现对三个队列的具体操作。具体的驱动可以采用时间片算法或

手动调度的形式完成三个状态之间的转换4、用switch 选择语句选择状态。 5、按照自己的设定能完成所有的状态转换的运行(包括创建和运行结束)。 三、实验步骤 1、复习进程管理三状态模型部分内容。 2、预习C++ Builder或VC++、Delphi、JBuilder线程编程。 3、运行示例程序,进一步明确实验要求。可以采用控制台模式或窗口模式。 4、上机编程、调试程序。 5、完成实验报告。 四、实验过程 1、进程管理三状态模型部分内容 进程从因创建而产生直至撤销而消亡的整个生命周期中,有时占用处理器执行,有时虽然可以运行但分不到处理器,有时虽然处理器空闲但因等待某个事件发生而无法执行,这一切都说明进程和程序不同,进程是活动的且有状态变化,状态及状态之间的转换体现进程的动态性,为了便于系统管理,一般来说,按照进程在执行过程中的不同情况至少要定义三种进程状态。 (1)运行态:进程占用处理器运行的状态。

(2)就绪态:进程具备运行条件,等待系统分配处理器以便起运行的状态。(3)等待态:进程不具备运行条件,正在等待某个时间完成的状态。2、程序设计环境

操作系统进程管理实验报告

进程管理 2.1 实验目的 ●加深对进程概念的理解,明确进程和程序的区别。 ●进一步认识并发执行的实质。 ●分析进程争用资源的现象,学习解决进程互斥的方法。 2.2 背景知识 1、fork() 创建一个新进程 int fork() 其中返回int取值意义如下: 0:创建子进程,从子进程返回的id值 大于0:从父进程返回的子进程id值 -1:创建失败 2、lockf(files,function,size):用于锁定或打开锁定一个共享文件 用作锁定文件的某些段或者整个文件,本函数适用的头文件为: #include 参数定义: int lockf(files,function,size) int files,function; long size; 其中:files是文件描述符,习惯上,标准输入(standard input)的文件描述符是0,标准输出(standard output)是1,标准错误(standard error)是2(lockf(1,1,0)是锁定屏幕输出,不让其他进程输出到屏幕)lockf(1,0,0)则是解锁。function是锁定和解锁;1表示锁定,0表示解锁。size是锁定和解锁的字节数,若用0,表示从文件的当前位置到文件尾。

2.3实验内容 2.3.1进程创建 编写一段程序,利用系统调用fork( )创建两个进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。 2.3.2进程控制 修改已经编好的程序,将每个进程输出一个字符改为每个进程输出一句话,在观察程序执行时屏幕上出现的现象,并分析原因。 如果在程序中使用系统调用lockf()来给每一个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。 2.3.3参考程序 #include Main() { Int p1,p2; While ((p1=fork())= =-1); If (p1= =0) Putchar(…b?); Else { While ((p2=fork()= =-1); If (p2= =0) Putchar(…c?); Else Putchar(…a?); } } 分析:从进程并发执行来看,输出bac,acb或bca都有可能。 原因:fork()创建进程所需要的时间要多于输出一个字符的时间,因此在主进程创建进程2的同时,进程1就输出了”b”,而进程2和主程序的输出次序是有随机性的,所以会出现多种可能结果。 进程控制源程序:

相关主题
文本预览
相关文档 最新文档