文档库 最新最全的文档下载
当前位置:文档库 › 第3单元 进程管理(5)

第3单元 进程管理(5)

实验三-进程管理

实验三进程管理 一、实验目的 1.熟悉和理解进程和进程树的概念,掌握有关进程的管理机制 2.通过进程的创建、撤销和运行加深对进程并发执行的理解 3.明确进程与程序、并行与串行执行的区别 4.掌握用C 程序实现进程控制的方法 二、实验学时 2学时 三、实验背景知识 所涉及的系统调用 1、exec( )系列(exec替换进程映像) 系统调用exec( )系列,也可用于新程序的运行。fork( )只是将父进程的用户级上下文拷贝到新进程中,而exec( )系列可以将一个可执行的二进制文件覆盖在新进程的用户级上下文的存储空间上,以更改新进程的用户级上下文。exec( )系列中的系统调用都完成相同的功能,它们把一个新程序装入内存,来改变调用进程的执行代码,从而形成新进程。如果exec( )调用成功,调用进程将被覆盖,然后从新程序的入口开始执行,这样就产生了一个新进程,新进程的进程标识符id 与调用进程相同。 exec( )没有建立一个与调用进程并发的子进程,而是用新进程取代了原来进程。所以exec( )调用成功后,没有任何数据返回,这与fork( )不同。exec( )系列系统调用在UNIX系统库unistd.h中,共有execl、execlp、execle、execv、execvp五个,其基本功能相同,只是以不同的方式来给出参数。 #include int execl(const cha r *pathname, const char *arg, …); int execlp(const char *, const char *arg, …); int execle(const char *pathname, const char *arg, …, const char *envp[ ]); int execv(const char *pathname, char *const argv[ ]); int execvp(const char *, char *const argv[ ]); 参数: path参数表示你要启动程序的名称包括路径名。 arg参数表示启动程序所带的参数,一般第一个参数为要执行命令名,不是带路径且arg必须以NULL结束。 返回值:成功返回0,失败返回-1 注:上述exec系列函数底层都是通过execve系统调用实现. 1)带l 的exec函数:execl,execlp,execle,表示后边的参数以可变参数的形式给出且都以一个空指针结束。 #include

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

实验一进程管理 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

实验一 进程管理

实验一进程管理 【实验目的】 1)加深对进程概念及进程管理各部分内容的理解。 2)熟悉进程管理中主要数据结构的设计和进程调度算法、进程控制机构、同步机构、通讯机构的实施。 【实验要求】 调试并运行一个允许n 个进程并发运行的进程管理模拟系统。了解该系统的进程控制、同步及通讯机构,每个进程如何用一个PCB 表示、其内容的设置;各进程间的同步关系;系统在运行过程中显示各进程的状态和有关参数变化情况的意义。 【实验环境】 具备Windows或MS-DOS操作系统、带有Turbo C 集成环境的PC机。 【实验重点及难点】 重点:理解进程的概念,进程管理中主要数据结构的设计和进程调度算法、进程控制机构、同步机构、通讯机构的实施。 难点:实验程序的问题描述、实现算法、数据结构。 【实验内容】 一.阅读实验程序 程序代码见【实验例程】。 二.编译实验例程 用Turbo C 编译实验例程。 三.运行程序并对照实验源程序阅读理解实验输出结果的意义。 【实验例程】 #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() { 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) 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("times silce interrupt'\n process%d enter into ready.\n",exe+1); exe=NIL; return(TRUE); } scheduler()

操作系统实验二(进程管理)

操作系统进程管理实验 实验题目: (1)进程的创建编写一段程序,使用系统调用fork( )创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。试观察记录屏幕上的显示结果,并分析原因。 (2)进程的控制修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,在观察程序执行时屏幕上出现的现象,并分析原因。 (3)编制一段程序,使其实现进程的软中断通信。要求:使用系统调用fork( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上来的中断信号(即按Del键);当捕捉到中断信号后,父进程调用系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:Child process 1 is killed by parent! Child process 2 is killed by parent! 父进程等待两个子进程终止后,输出如下的信息后终止:Parent process is killed! 在上面的程序中增加语句signal(SIGINT, SIG_IGN)和signal(SIGQUIT, SIG_IGN),观察执行结果,并分析原因。 (4)进程的管道通信编制一段程序,实现进程的管道通信。使用系统调用pipe( )建立一条管道线;两个进程P1和P2分别向管道各写一句话:Child 1 is sending a message! Child 2 is sending a message! 而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。要求父进程先接收子进程P1发来的消息,然后再接收子进程P2发来的消息。 实验源程序及报告: (1)、进程的创建 #include int main(int argc, char *argv[]) { int pid1,pid2; /*fork first child process*/ if ( ( pid1=fork() ) < 0 ) { printf( "ProcessCreate Failed!"); exit(-1); }

Linux 进程管理实验

Linux 进程管理实验 一、实验内容: 1. 利用bochs观测linux0.11下的PCB进程控制结构。 2. 利用bochs观测linux0.11下的fork.c源代码文件,简单分析其中的重要函数。 3. 在fork.c适当位置添加代码,以验证fork函数的工作原理。 二、Linux进程管理机制分析 Linux有两类进程:一类是普通用户进程,一类是系统进程,它既可以在用户空间运行,又可以通过系统调用进入内核空间,并在内核空间运行;另一类叫做内核进程,这种进程只能在内核空间运行。在以i386为平台的Linux系统中,进程由进程控制块,系统堆栈,用户堆栈,程序代码及数据段组成。Linux系统中的每一个用户进程有两个堆栈:一个叫做用户堆栈,它是进程运行在用户空间时使用的堆栈;另一个叫做系统堆栈,它是用户进程运行在系统空间时使用的堆栈。 1.Linux进程的状态: Linux进程用进程控制块的state域记录了进程的当前状态,一个Linux 进程在它的生存期中,可以有下面6种状态。 1.就绪状态(TASK_RUNNING):在此状态下,进程已挂入就绪队列,进入准备运行状态。 2.运行状态(TASK_RUNNING):当进程正在运行时,它的state域中的值不改变。但是Linux会用一个专门指针(current)指向当前运行的

任务。 3.可中断等待状态(TASK_INTERRUPTIBLE):进程由于未获得它所申请的资源而处在等待状态。不管是资源有效或者中断唤醒信号都能使等待的进程脱离等待而进入就绪状态。即”浅睡眠状态”。 4.不可中断等待状态(TASK_UNINTERRUPTIBLE):这个等待状态与上面等待状态的区别在于只有当它申请的资源有效时才能被唤醒,而其它信号不能。即“深睡眠状态”。 5.停止状态(TASK_STOPPED):当进程收到一个SIGSTOP信号后就由运行状态进入停止状态,当收到一个SINCONT信号时,又会恢复运行状态。挂起状态。 6.终止状态(TASK_ZOMBIE):进程因某种原因终止运行,但进程控制块尚未注销。即“僵死状态”。 状态图如下所示: 2.Linux进程控制块:

实验报告三进程管理及进程通信

实验三进程管理及进程通信 实验环境: Linux操作系统 实验目的: (1)利用Linux提供的系统调用设计程序,加深对进程概念的理解。 (2)体会系统进程调度的方法和效果。 (3)了解进程之间的通信方式以及各种通信方式的使用。 实验方法: 用vi 编写c 程序(假定程序文件名为prog1.c)编 译程序 $ gcc -o prog1.o prog1.c 或 $ cc -o prog1.o prog1.c 运行 $./prog1.o 实验内容及步骤: 实验1 编写程序。显示进程的有关标识(进程标识、组标识、用户标识等)。经过5 秒钟后,执行另一个程序,最后按用户指示(如:Y/N)结束操作。 编程截图:

运行结果: 实验2 参考例程1,编写程序。实现父进程创建一个子进程。体会子进程与父进程分 别获得不同返回值,进而执行不同的程序段的方法。 例程1:利用fork()创建子进程 /* 用fork()系统调用创建子进程的例子*/ main() { int i; if (fork()) /*父进程执行的程序段*/ i=wait(); /* 等待子进程结束*/{ printf("It is parent process.\n"); printf("The child process,ID number %d, is finished.\n",i); } else{

Printf(“It is child process.\n”); Sleep(10); Exit(); } } 运行结果: 思考: 子进程是如何产生的?又是如何结束的?子进程被创建后它的运行环境是怎样建立的? 答:是由父进程用fock()函数创建形成的,通过exit()函数自我结束,子进程被创建后核心 将其分配一个进程表项和进程标识符,检查同时运行的进程数目,并且拷贝进程表项的数据,由子进程继承父进程所有文件。 实验3 参考例程2,编写程序。父进程通过循环语句创建若干子进程。探讨进程的家族树 以及子进程继承父进程的资源的关系。 例程2:循环调用fork()创建多个子进程。 /*建立进程树*/ #include main() { int i; printf(“My pid is %d, my father’s pid is %d\n”,getpid() ,getppid()); for(i=0; i<3; i++) if(fork()==0) printf(“%d pid=%d ppid=%d\n”, i,getpid(),getppid()); else { j=wait(0); Printf(“%d:The chile %d is finished.\n”,getpid(),j);

进程管理实验报告

进程管理实验报告 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()是如何创建进程的?

实验三《进程管理》

实验三进程间的通信 (一)信号机制实验 一.参考程序 #include #include #include Void waiting(),stop(); Intwait_mark; Main() { Int P1,P2,stdout; While((P1=fork())==-1); /*创建子进程P1*/ If(P1>0) { While((p2=fork())==-1); /*创建子进程P2*/ If(P2>0) { Wait_mark=1; Signal(SIGINT,stop); /*接收到^C信号,转stop*/ Waiting(); Kill(P1,16); /*向P1发软中断信号16*/ Kill(P2,17); /*向P2发软中断信号17*/ Wait(0); /*同步*/ Wait(0); Printf(“Parent process is killed!\n”); Exit(0); } Else { Wait_mark=1; Signal(17,stop); /*接收到软中断信号17,转stop*/ Waiting(); Lockf(stdout,1,0); Printf(“Child process 2 is killed by parent!\n); Lockf(stdout,0,0); Exit(0); }

} Else { Wait_mark=1; Signal(16,stop); /*接收到软中断信号16,转stop*/ Waiting(); Lockf(stdout,1,0); Printf(“Child process 1 is killed by parent!\n”); Lockf(stdout,0,0); Exit(0); } } Void waiting() { While(wait_mark!=0); } Void stop() { Wait_mark=0; } 二.思考: 1.该程序段前面部分用了两个wait(0),他们起什么作用? 解:用了两个wait(0)的作用是同时使两个子进程P1和P2发出软中断信号,而不用等待。 2.该程序段中每个进程退出时都用了语句exit(0),为什么? 解:用exit(0)的作用是使子进程实现自我终止,正常退出此次操作,返回操作系统。 3.为何预期的结果并未显示出来? 解:因为只执行成功两个子进程,但是并没有调用两个子进程P1,P2。当signal()让父进程捕捉从键盘上来的信号(按下^C或者break键时),只有捕捉到信号后,父进程用系统调用kill()向两个子进程发出信号。当子进程捕捉到信号后才能输出信息,之后父进程输出信息。 4.程序该如何修改才能得到正确结果? 5.不修改程序如何得到期望的输出?

第三章进程管理课后习题答案解析

进程管理习题 1现代操作系统中为什么要引入“进程”概念? 它与程序有什么区别? 答:之所以要引入进程的概念,是因为在一些可以并发的程序段之间,存在着某种相互制约的关系,每个程序段的执行不仅要受到其它程序执行的制约,而且还要动态地依赖系统资源的分配情况,因此每个可以并发执行的程序段就会因外界条件的限制而不能运行,被迫处于阻塞状态。仅用程序的概念无法表示程序的走走停停以及程序运行过程中对资源的竞争现象,因此需要采用一种动态的概念描述并发程序这种走走停停的现象,这就产生了进程的概念。 进程和程序的区别: (1)进程是程序的执行过程,是动态的过程,属于一种动态概念。程序是一组有序静态指令和数据的集合,用来指示处理机的操作,是一种静态概念。 (2)从结构上看,每个进程实体是由程序段和相应的数据段两部分构成,并且进程结构中还要包含PCB,即进程控制块。 (3)一个进程可以涉及到一个或几个程序的执行;反之,同一程序可以对应多个进程,即同一个程序段可以在不同数据集合上运行,可以构成不同的进 程。 (4)进程能真实地描述并发执行的过程,而程序仅仅是静态指令堆积的序列。 (5)进程有可创建其他进程的功能,而一般的程序不具有创建其它程序的功能。 (6)每一个程序都是在一个进程现场中运行的。 2叙述进程的并发性和制约性。 答:并发性是进程的重要特征。即多道程序中多个进程同时向前推进的过程,没个进程总是与其它进程并发地执行的。进程的制约性是指一个进程的运行受到另一进程的制约。比如有的进程可能正在等待另一进程的计算结果而无法运行,或者进程所需的资源被别的进程占有而无法运行。 3进程的含义是什么? 如何构造和描述进程? 答:进程是程序的一次执行。进程由“进程控制块+程序+数据”构成,用进程控制块描述进程。 4有三个并发进程,R负责从输入设备读入信息并传送给M,M将信息加工并传送给P,P将打印输出,写出下列条件下的并发程序。 (1) 双缓冲区,每个区大小为K。 (2) 单缓冲区,其大小为K。 答: (1)双缓冲区,每个区大小为K,信号量初值如下: mutexR=mutexP=1; emptyR=emptyP=k; fullR= fullP=0; 变量的初值如下: inR=outR=inP=outP=0; 用类Pascal编写程序如下:

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

计算机与信息工程学院实验报告 一、实验内容 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

实验三 进程管理

实验三进程管理 背景知识 Windows所创建的每个进程都从调用CreateProcess() API函数开始,该函数的任务是在对象管理器子系统内初始化进程对象。每一进程都以调用ExitProcess() 或TerminateProcess() API函数终止。通常应用程序的框架负责调用ExitProcess() 函数。对于C++ 运行库来说,这一调用发生在应用程序的main() 函数返回之后。 1. 创建进程 CreateProcess() 调用的核心参数是可执行文件运行时的文件名及其命令行。表3-4详细地列出了每个参数的类型和名称。 可以指定第一个参数,即应用程序的名称,其中包括相对于当前进程的当前目录的全路径或者利用搜索方法找到的路径;lpCommandLine参数允许调用者向新应用程序发送数据;接下来的三个参数与进程和它的主线程以及返回的指向该对象的句柄的安全性有关。 然后是标志参数,用以在dwCreationFlags参数中指明系统应该给予新进程什么行为。经常使用的标志是CREA TE_SUSPNDED,告诉主线程立刻暂停。当准备好时,应该使用ResumeThread() API来启动进程。另一个常用的标志是CREATE_NEW_CONSOLE,告诉新进程启动自己的控制台窗口,而不是利用父窗口。这一参数还允许设置进程的优先级,用以向系统指明,相对于系统中所有其他的活动进程来说,给此进程多少CPU时间。 接着是CreateProcess() 函数调用所需要的三个通常使用缺省值的参数。第一个参数是lpEnvironment参数,指明为新进程提供的环境;第二个参数是lpCurrentDirectory,可用于向主创进程发送与缺省目录不同的新进程使用的特殊的当前目录;第三个参数是STARTUPINFO数据结构所必需的,用于在必要时指明新应用程序的主窗口的外观。 CreateProcess() 的最后一个参数是用于新进程对象及其主线程的句柄和ID的返回值缓冲区。以PROCESS_INFORMA TION结构中返回的句柄调用CloseHandle() API函数是重要

实验三 进程管理与系统监视

实验三进程管理与系统监视 实验目的 (1)熟练掌握手工启动前后台作业的方法; (2)熟练掌握有关进程与作业管理的Shell命令; (3)掌握at调度和cron调度的设置方法; (4)了解进行系统性能监视的基本方法 实验内容 1、作业和进程的基本管理 [操作要求1]前台启动行编辑器vi并打开文件f4,然后挂起vi,最后在后台启动一个查找inittab文件的find作业,查询结果保存到文件f5 [操作步骤] (1)进入终端字符界面,切换到超级用户; (2)输入命令“vi f4”,在前台启动行编辑器并打开编辑文件f4; (3)通过[Ctrl+Z]暂时挂起vi文本编辑器,屏幕将显示该作业的作业号1; (4)输入命令“find /etc/ -name inittab > f5&”,启动后台find作业,屏幕将给出该作业的作业号2和进程号。 [操作要求2]查看当前系统中的作业、进程和用户信息,并对作业进行前后切换 [操作步骤] (1)输入命令“fg 2”,将2号作业切换到前台;稍等片刻作业完成后将出现提示符; (2)输入命令“jobs”,查看当前系统的所有作业,注意作业vi f4和find的相关信息; (3)输入命令“cat f5”,查看find命令的执行结果; (4)通过命令“jobs”,再次查看当前系统作业,现在只有一个挂起作业vi f4; (5)输入命令“kill –9 %1”,强制终止指定作业(作业号为1的vi f4作业); (6)片刻后再次查看当前系统作业的情况(输入命令“jobs”),当前并无任何作业; (7)输入命令“ps -l”,查看进程的相关信息,注意显示信息项的含义; (8)输入命令“who -H”,查看用户的详细信息,注意显示信息项的含义。 ps命令各输出项的含义为: S(state):进程状态,其中R表示运行状态;S表示休眠状态;T表示暂停或终止状态;Z表示僵死状态 UID(User ID):进程启动者的用户ID PID(ProcessID):进程号 PPID:父进程的进程号 NI(Nice):进程的优先级值

第3章 进程管理 习题

第3章进程管理 一、单项选择题 1.在多进程的系统中,为了保证公共变量的完整性,各进程应互斥进入临界区。所谓临界区是指。(清华大学1996年研究生试题) a.一个缓冲区 b. 一段数据区 c. 同步机制 d.. 一段程序 2. 一个进程是。(清华大学1996年研究生试题) a.由协处理机执行的一个程序 b.一个独立的程序+数据集 c.PCB结构与程序和数据的组合 d.一个独立的程序 3.在操作系统中,信号量表示资源实体,是一个与队列有关的变量,其值仅能用P、V操作来改变。(陕西省1995年自考题) a.实型 b.整型 c.布尔型 d.记录型 4.设有5个进程共享一个互斥段,如果最多允许有3个进程同时进入互斥段,则所采用的互斥信号量的初值应是。(陕西省1996年自考题) a. 5 b. 3 c. 1 d. 0 5.并发进程之间。(陕西省1997年自考题) a.彼此无关 b、必须同步 c、必须互斥 d、可能需要同步或互斥6.实现进程之间同步与互斥的通信工具为。 a、P、V操作 b、信箱通信 c、消息缓冲 d、高级通信 7.N个进程共享某一临界资源,则互斥信号量的取值范围为。 a、0~1 b、-1~0 c、1~ -(N-1) d、0~ -(N-1) 8.设m为同类资源数,n为系统中并发进程数。当n个进程共享m个互斥资源时,每个进程的最大需求是w;则下列情况会出现系统死锁的是。 a、m=2,n=1,w=2 b、m=2,n=2,w=1 c、m=4,n=3,w=2 d、m=4,n=2,w=3 9.是进程调度算法。 a、时间片轮转法 b、先来先服务 c、响应比高者优先 d、均衡调度算法10.当时,进程从执行状态转变为就绪状态。 (西北工业大学1999年研究生试题) a、进程被调度程序选中 b、时间片到 b、等待某一事件 d、等待的事件发生 11.对两个并发进程,其互斥信号量为mutex;若mutex=0,则表明。 a、没有进程进入临界区 b、有一个进程进入临界区 c、一个进程进入临界区而另一个进程正处于等待进入临界区状态 d、有两个进程进入临界区 12.用P、V操作可以解决互斥问题。 A、某些 b、一个 c、一切 d、大多数 13.系统中有n(n>2)个进程,并且当前没有执行进程调度程序,则不可能发生。 A、有一个运行进程,没有就绪进程,剩下的n-1个进程处于等待状态 B、有一个运行进程和n-1个就绪进程,但没有进程处于等待状态 C、有一个运行进程和1个就绪进程,剩下的n-2个进程处于等待状态 D、没有运行进程但有2个就绪进程,剩下的n-2个进程处于等待状态

实验二 进程控制

实验四进程控制 【实验目的】 1、掌握进程的概念,明确进程和程序的区别。 2、认识和了解并发执行的实质。 3、分析进程争用资源的现象,学习解决进程互斥的方法。 【实验内容】 1、进程的创建(必做题) 编写一段程序,使用系统调用fork( )创建两个子进程,在系统中有一个父进程和两个子进程活动。让每个进程在屏幕上显示一个字符;父进程显示字符“a”,子进程分别显示字符“b”和“c”。试观察记录屏幕上的显示结果,并分析原因。 <参考程序> # 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’); } } 2、修改已编写的程序,将每个进程的输出由单个字符改为一句话,再观察程序执行时屏幕上出现的现象,并分析其原因。(必做题) <参考程序> # include main() { int p1, p2, i; while((p1=fork())= = -1); if(p1= =0) for(i=0;i<500;i++) printf(“child%d\n”,i); else

If(p2= =0) for(i=0;i<500;i++) printf(“son%d \n”,i); else for(i=0;i<500;i++) printf(“daughter%d \n”,i); } } 3、编写程序创建进程树如图1和图2所示,在每个进程中显示当前进程识别码和父进程识别码。(必做题) 【思考题】 1、系统是怎样创建进程的? 2、当首次调用新创建进程时,其入口在哪里? 3、当前运行的程序(主进程)的父进程是什么? 【实验报告】 1、列出调试通过程序的清单,分析运行结果。 2、给出必要的程序设计思路和方法(或列出流程图)。 3、回答思考题。 4、总结上机调试过程中所遇到的问题和解决方法及感想。 #include main() {int p1,p2,p3; while((p1=fork())==-1); if(p1==0) { while((p2=fork())==-1); if(p2==0) { 父进程 图1 进程树 图2 进程树

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

实验内容:进程管理 一、实验目的 1、掌握Linux中进程的创建方法及执行情况; 2、加深对进程、进程树等概念的理解; 3、掌握Linux中如何加载子进程自己的程序; 4、掌握父进程通过创建子进程完成某项任务的方法; 5.、掌握系统调用exit()和_exit()调用的使用。 6、分析进程竞争资源的现象,学习解决进程互斥的方法;进一步认识并发执行的实质 二、实验内容 (一)进程的创建 1、编写一段程序,使用系统调用fork( )创建两个子进程。当此程序运行时,在系统中 有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符。 #include main() { int p,x; p=fork(); if(p>0) { x=fork(); if(x>0) printf("father\n"); else printf("child2"); } else printf("child1"); } 输出结果: child1 child2 father 2、运行以下程序,分析程序执行过程中产生的进程情况。 #include main() { int p,x; p=fork(); if (p>0) fork(); else{ fork();

fork(); } sleep(15); } 实验步骤: 编译连接 gcc –o forktree forktree.c 后台运行 ./forktree & 使用 pstree –h 查看进程树 运行结果: ├─gnom e-terminal─┬─bash─┬─forktree─┬─forktree─┬─forktr ee───forktree ││││└─forktree │││└─forktree ││└─pstree 分析:程序运行,系统首先创建一个进程forktree,执行到p=fork()创建一个子进程forktree,子进程获得处理机优先执行,父进程等待;执行else,当执行到第一个fork()函数时,子进程创建了一个进程forktree,称之为孙进程,孙进程获得处理机往下执行,子进程等待;执行到第二个fork()函数时,孙进程又创建一个进程forktree,称之为重孙进程,重孙进程很快执行完,将处理机还给孙进程,孙进程很快执行完,将处理机还给子进程;子进程继续往下执行,执行到第二个fork()函数,又创建一个进程forktree,称之为第二孙进程,并获得处理机执行,此进程很快执行完,将处理机还给子进程,子进程也很快执行完,将处理机还给父进程,父进程P>0执行if语句,运行fork()函数,又创建一个进程forktree,称之为第二子进程,此进程获得处理机执行很快运行完,将处理机还给父进程,父进程运行sleep(15)语句,休眠15秒,用pstree命令查询进程树。 3、运行程序,分析运行结果。 #include main() { int p,x,ppid,pid; x=0; p=fork(); if(p>0) { printf("parent output x=%d\n",++x); ppid=getpid(); printf("Thi id number of parent is:ppid=%d\n",ppid); } else { printf("child output x=%d\n",++x); pid=getpid(); printf("Thi id number of child is:pid=%d\n",pid);

进程管理实验报告

实验名称: 进程管理 实验要求:阅读后面的C语言实例,修改程序,使其优先数在运行期间可以变化(动态优先 数)。例如,当某进程被时间片中断次数增加到一定数目时,提高其优先权。关键问题:读懂源程序代码,了解进程管理的方式,并设计一个算法使程序能在运行过程中修改进程优先级。 设计思路:在进程控制块中定义一个记录进程中断次数的变量,在block函数中设置跟踪并 记录进程中断次数,在调度函数schedule中设置算法,在进程中断3次后将该 进程的优先级提升至最高。 改动后的代码: #include #define TRUE 1 #define FALSE 0 #define MAXPRI 100 #define NIL -1 //进程控制块 struct { int id; //进程号 char status; //进程状态,'e'-执行态'r'-高就绪态't'-低就绪态'w'-等待态'c'-完成态 int nextwr; //等待链指针,指示在同一信号量上等待的下一个等待进程的进程号。 int priority; //进程优先数,值越小,优先级越高。 int c;//进程中断次数 }pcb[3];//共3个进程 //s1、s2为三个进程共享的变量;seed为随机值;registeri模拟寄存器值,存放计算的重复次数。 int registeri,s1,s2,seed,exe=NIL;//exe为当前运行(占有cpu)的进程号 //2个信号量sem[0]、sem[1],分别与共享变量s1、s2相联系。 //对应信号量sem[0]、sem[1]分别有两个阻塞队列,队列首由sem[].firstwr指定,队列链指针是pcb[].nextwr struct{ int value;//信号量值 int firstwr;//等待该信号量的阻塞队列的首个进程号 }sem[2];

实验三 进程管理

实验三进程管理 1 实验目的 1. 理解进程的概念,明确进程和程序的区别。 2. 理解并发执行的实质。 3. 掌握进程的睡眠、同步、撤销等进程控制方法。 2 实验内容 1. 进程的创建。 ①编写一段源程序,使系统调用fork()创建两个子进程,当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。试观察记录屏幕上的显示结果,并分析原因。 ②修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,在观察程序执行时屏幕出现的现象,并分析原因。 2. 进程的控制 ①用fork()创建一个进程,再调用exec()用新的程序替换该子进程的内容。 ②利用wait()来控制进程执行顺序。 3 实验准备 3.1 进程 Linux中,进程既是一个独立拥有资源的基本单位,又是一个独立调度的基本单位。一个进程实体由若干个区(段)组成,包括程序区、数据区、栈区、共享存储区等。每个区又分为若干页,每个进程配置有唯一的进程控制块PCB,用于控制和管理进程。 PCB的数据结构如下: 1. 进程表项(Process Table Entry) 包括一些最常用的核心数据如:进程控制符PID、用户标识符UID、进程状态、事件描述符、进程和U区在内存或外存的地址、软中断信号、计时域、进程的大小、偏置值Nice、指向就绪队列中下一个PCB的指针P_Link、指向U区进程正文、数据及栈在内存区域的指针等。 2. U区(U Area) 用于存放进程表项的一些扩充信息。每一个进程都会有一个私用的U区,其中包含:进程表项指针、真正用户标识符u-ruid(read user ID)、有效用户标识符u-euid(effective user ID)、用户文件描述符表、计时器、内部I/O参数、限制字段、差错字段、返回值、信号处理数组。 3. 系统区表项 系统区表项用来存放各个段在物理存储器中的位置等信息。系统把一个进程的虚地址空间划分为若干个连续的逻辑区,有正文区、数据区、栈区等。这些区是可被共享和保护的独立实体,多个进程可共享一个区。为了对区进行管理,核心中设置一个系统区表,各表项中记录了以下有关描述活动区的信息: 区的类型和大小、区的状态、区在物理存储器中的位置、引用计数、指向文件索引节点的指针。 4. 进程区表 系统为每个进程配置了一张进程区表。其中,每一项记录一个区的起始虚地址及指向系统区表中对应的区表项。内核通过查找进程区表和系统区表,便可将区的逻辑地址变换为物理地址。

相关文档