ImageVerifierCode 换一换
格式:DOCX , 页数:18 ,大小:96.49KB ,
资源ID:11957253      下载积分:10 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/11957253.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(实验一进程管理.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

实验一进程管理.docx

1、实验一 进程管理实验一 进程管理1. 实验目的 加深对进程概念的理解,明确进程和程序的区别; 进一步认识并发执行的实质; 分析进程争用资源的现象,学习解决进程互斥的方法; 了解Linux系统中进程通信的基本原理。2. 实验准备 阅读Linux的sched.h源码文件,加深对进程管理的理解。 阅读Linux的fork.h源码文件,分析进程的创建过程。3. 实验内容 进程的创建编写一段程序,使用系统调用fork ( )创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程显示字符“b”和字符“c”。试观察记录屏幕上的显示

2、结果,并分析原因。 进程的控制修改已编写的程序,将每个进程输出一个字符改为每个进程输出一句话,再观察程序执行时屏幕上出现的现象,并分析原因。如果在程序中使用系统调用lockf ( )来给每一个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。 软中断通信编制一段程序实现进程的软中断通信。要求:使用系统调用fork ( )创建两个子进程,再用系统调用signal( )让父进程捕捉键盘上发来的中断信号(既按Del键);当捕捉到中断信号后,父进程系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:Child process 1 is killed by par

3、ent!Child process 2 is killed by parent!父进程等待两个子进程终止后,输出如下的信息后终止:Parent process is killed!在上面的程序中增加语句signal (SIGINT, SIG_IGN) 和signal (SIGQUIT, SIG_IGN),观察执行结果,并分析原因。4. 实验指导1) 进程LINUX 中,进程既是一个独立拥有资源的基本单位,又是一个独立调度的基本单位。一个进程实体由若干个区(段)组成,包括程序区、数据区、栈区、共享存储区等。每个区又分为若干页,每个进程配置有唯一的进程控制块 PCB,用于控制和管理进程。PCB 的

4、数据结构如下:(A) 进程表项(Process Table Entry)。包括一些最常用的核心数据:进程标识符 PID、用户标识符 UID、进程状态、事件描述符、进程和 U 区在内存或外存的地址、软中断信号、计时域、进程的大小、偏置值 nice、指向就绪队列中下一个PCB 的指针 P_Link、指向 U 区进程正文、数据及栈在内存区域的指针。(B) U 区(U Area)。用于存放进程表项的一些扩充信息。每一个进程都有一个私用的 U 区,其中含有:进程表项指针、真正用户标识符uruid(read user ID)、有效用户标识符 ueuid(effective user ID)、用户文件描述符

5、表、计时器、内部 I/O 参数、限制字段、差错字段、返回值、信号处理数组。由于 LINUX 系统采用段页式存储管理,为了把段的起始虚地址变换为段在系统中的物理地址,便于实现区的共享。(C) 系统区表项。以存放各个段在物理存储器中的位置等信息。系统把一个进程的虚地址空间划分为若干个连续的逻辑区,有正文区、数据区、栈区等。这些区是可被共享和保护的独立实体,多个进程可共享一个区。为了对区进行管理,核心中设置一个系统区表,各表项中记录了以下有关描述活动区的信息:区的类型和大小、区的状态、区在物理存储器中的位置、引用计数、指向文件索引结点的指针。(D) 进程区表系统为每个进程配置了一张进程区表。表中,每

6、一项记录一个区的起始虚地址及指向系统区表中对应的区表项。核心通过查找进程区表和系统区表,便可将区的逻辑地址变换为物理地址。2) 进程映像LINUX 系统中,进程是进程映像的执行过程,也就是正在执行的进程实体。它由三部分组成:(A) 用户级上下文。主要成分是用户程序;(B) 寄存器上下文。由 CPU 中的一些寄存器的内容组成,如 PC,PSW,SP 及通用寄存器等;(C) 系统级上下文。包括 OS 为管理进程所用的信息,有静态和动态之分。3) 所涉及的系统调用(A) fork( ),创建一个新进程,并复制进程,使父子进程内容几乎相同。系统调用格式:pid = fork( )参数定义:int fo

7、rk( )fork( )返回值意义如下:0:在子进程中,pid 变量保存的 fork( )返回值为 0,表示当前进程是子进程。0:在父进程中,p id 变量保存的 fork( )返回值为子进程的 id 值( 进程唯一标识符)。-1:创建失败。如果 fork( )调用成功,它向父进程返回子进程的 PID,并向子进程返回 0,即fork( )被调用了一次,但返回了两次。此时 OS 在内存中建立一个新进程,所建的新进程是调用fork( )父进程(parent process)的副本,称为子进程(child process)。子进程继承了父进程的许多特性,并具有与父进程完全相同的用户级上下文。父进程与

8、子进程并发执行。核心为 fork( )完成以下操作:a) 为新进程分配一进程表项和进程标识符进入 fork( )后,核心检查系统是否有足够的资源来建立一个新进程。若资源不足,则fork( )系统调用失败;否则,核心为新进程分配一进程表项和唯一的进程标识符。b) 检查同时运行的进程数目超过预先规定的最大数目时,fork( )系统调用失败。c) 拷贝进程表项中的数据将父进程的当前目录和所有已打开的数据拷贝到子进程表项中,并置进程的状态为“创建”状态。d) 子进程继承父进程的所有文件对父进程当前目录和所有已打开的文件表项中的引用计数加 1。e) 为子进程创建进程上、下文进程创建结束,设子进程状态为“

9、内存中就绪”并返回子进程的标识符。f) 子进程执行虽然父进程与子进程程序完全相同,但 每个进程都有自己的程序计数器 PC(注意子进程的 PC 开始位置),然后根据 pid 变量保存的 fork( )返回值的不同,执行了不同的分支语句。(B) wait( )等待子进程运行结束。如果子进程没有完成,父进程一直等待。wait( )将调用进程挂起,直至其子进程因暂停或终止而发来软中断信号为止。如果在 wait( )前已有子进程暂停或终止,则调用进程做适当处理后便返回。系统调用格式:int wait(status)int *status其中,status 是用户空间的地址。它的低 8 位反应子进程状态,

10、为0 表示子进程正常结束,非 0 则表示出现了各种各样的问题;高 8 位则带回了 exit( )的返回值。exit( )返回值由系统给出。核心对 wait( )作以下处理:a) 首先查找调用进程是否有子进程,若无,则返回出错码;b) 若找到一处于“僵死状态”的子进程,则将子进程的执行时间加到父进程的执行时间上,并释放子进程的进程表项;c) 若未找到处于“僵死状态”的子进程,则调用进程便在可被中断的优先级上睡眠,等待其子进程发来软中断信号时被唤醒。(C) exit( )终止进程的执行。系统调用格式:void exit(status)int status其中,status 是返回给父进程的一个整数

11、,以备查考。为了及时回收进程所占用的资源并减少父进程的干预,LINUX/LINUX 利用 exit( )来实现进程的自我终止,通常父进程在创建子进程时,应在进程的末尾安排一条 exit( ),使子进程自我终止。exit(0)表示进程正常终止,exit(1)表示进程运行有错,异常终止。如果调用进程在执行 exit( )时,其父进程正在等待它的终止,则父进程可立即得到其返回的整数。核心须为 exit( )完成以下操作:a) 关闭软中断b) 回收资源c) 写记帐信息d) 置进程为“僵死状态”(D) lockf(files,function,size): 用作锁定文件的某些段或者整个文件,本函数适用的

12、头文件为: #include 参数定义: int lockf(files,function,size) int files,function; long size; 其中:files是文件描述符:function是锁定和解锁;1表示锁定,0表示解锁。size是锁定和解锁的字节数,若用0,表示从文件的当前位置到文件尾。(E) signal(sig,function): 允许调用进程控制软中断信号的处理。 头文件为: #include 参数定义: signal(sig,function); int sig; void(*func)(); 其中:sig的值是: SIGHVP 挂起 SIGINT 键盘

13、按c键或break键 SIGQUIT 键盘按quit键 SIGILL 非法指令 SIGIOT IOT指令 SIGEMT EMT指令 SIGFPE 浮点运算溢出 SIGKILL 要求终止进程 SIGBUS 总线错 SIGSEGV 段违例 SIGSYS 系统调用参数错 SIGPIPE 向无读者管道上写 SIGALRM 闹钟 SIGTERM 软件终结 SIGUSRI 用户定义信号 SIGUSR2 第二个用户定义信号 SIGCLD 子进程死 SIGPWR 电源故障 function的解释如下: SIG_DEL:缺省操作。对除SIGPWR和SIGCLD外所有信号的缺省操作是进程终结对信号 SIGQUIT

14、,SIGILL,SIGTRA,SIGIOT,SIGEMT,SIGFPE,SIGBUS,SIGSEGV和SIGSYS它产生一内存映像文件。 SIG_IGN:忽视该信号的出现。 Function:在该进程中的一个函数地址,在核心返回用户态时,它以软中断信号的序号作为参数调用该函数,对除了信号SIGILL,SIGTRAP和SIGTWR以外的信号,核心自动地重新设置软中断信号处理程序的值为SIG_DEL,一个进程不能捕获SIGKILL信号。(F) KILL 功能描述:用于向任何进程组或进程发送信号。1#include23#include45intkill(pid_tpid,intsig);参数:pid

15、:可能选择有以下四种1. pid大于零时,pid是信号欲送往的进程的标识。2. pid等于零时,信号将送往所有与调用kill()的那个进程属同一个使用组的进程。3. pid等于-1时,信号将送往所有调用进程有权给其发送信号的进程,除了进程1(init)。4. pid小于-1时,信号将送往以-pid为组标识的进程。sig:准备发送的信号代码,假如其值为零则没有任何信号送出,但是系统会执行错误检查,通常会利用sig值为零来检验某个进程是否仍在执行。返回值说明: 成功执行时,返回0。失败返回-1,errno被设为以下的某个值 EINVAL:指定的信号码无效(参数 sig 不合法) EPERM;权限不

16、够无法传送信号给指定进程 ESRCH:参数 pid 所指定的进程或进程组不存在4) 参考程序 进程的创建#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); /*父进程执行*/bca(有时会出现bac等)从进程并发执行来看,输出bac,acb等情况都有可能

17、。fork()创建进程所需的时间虽然可能多于输出一个字符的时间,上面的三个进程没有同步措施,所以父进程与子进程的输出内容会叠加在一起。输出次序带有随机性。 进程的控制# include main ( )int p1, p2, iwhile ( p1=fork ( )= = -1);if (p1= =0)for (i=0; i50; i+) printf (“child %dn”, i);else while (p2=(fork ( )= = -1);if (p2= =0)for (i=0; i50; i+) printf (“son %dn”, i);elsefor (i=0; i50; i+

18、) printf (“daughter %dn”, i); child son daughter daughter 或child son child son daughter 等由于函数printf ( ) 输出的字符串之间不会被中断,因此,字符串内部的字符顺序输出时不变。但是,由于进程并发执行时的调度顺序和父子进程的抢占处理机问题,输出字符串的顺序和先后随着执行的不同而发生变化,这与打印单字符的结果相同。#include#include#include#includemain() int p1,p2,i; if(p1=fork() lockf(1,1,0); for(i=0;i50;i+)

19、printf(parent %dn,i); lockf(1,0,0); wait(0); /* 保证在子进程终止前,父进程不会终止*/ exit(0); else if(p2=fork() lockf(1,1,0); for(i=0;i50;i+) printf(son %dn,i); lockf(1,0,0); wait(0); /* 保证在子进程终止前,父进程不会终止*/ exit(0); else lockf(1,1,0); for(i=0;i50;i+) printf(daughter %dn,i); lockf(1,0,0); exit(0); 大致与未上锁的输出结果相同,也是随着执

20、行时间不同,输出结果的顺序有所不同。因为上述程序执行时,lockf(1,1,0)锁定标准输出设备,lockf(1,0,0)解锁标准输出设备,在lockf(1,1,0)与lockf(1,0,0)中间的for循环输出不会被中断,加锁与不加锁效果不相同。 软中断通信#include#include#include #includevoid waiting(),stop(),alarming();int wait_mark;main() int p1,p2; if(p1=fork() /*创建子进程p1*/ if(p2=fork() /*创建子进程p2*/ /父进程 wait_mark=1; sign

21、al(SIGINT,stop); /*接收到DEL信号,转stop*/ signal(SIGALRM,alarming);/*接受SIGALRM*/ 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); signal(SIGINT,SIG_IGN); /*忽略 c信号*/ while (wait_mark

22、!=0); lockf(1,1,0); printf(child process2 is killed by parent!n); lockf(1,0,0); exit(0); else wait_mark=1; signal(16,stop);signal(SIGINT,SIG_IGN); /*忽略c信号*/ while (wait_mark!=0); lockf(1,1,0); printf(child process1 is killed by parent!n); lockf(1,0,0); exit(0); void waiting() sleep(5);if (wait_mark!

23、=0) kill(getpid(),SIGALRM);void alarming() wait_mark=0;void stop() wait_mark=0;child process p1 is killed by parent!child process p2 is killed by parent!parent process is killed! 不做任何操作等待五秒钟父进程会在子进程先退出后再退出,并打印退出的顺序;或者点击ctrl+C后程序退出并打印退出的顺序。# include # include # include #includeint pid1, pid2;int EndF

24、lag=0, pf1=0, pf2=0;void IntDelete ( ) kill (pid1, 16); kill (pid2, 17); EndFlag=1; void Int1( )printf (“child process p1 is killed by parent!”)exit (0);void Int2 ( )printf (“child process p1 is killed by parent!”)exit (0);main ( ) int exited;signal (SIGINT, SIG_IGN);signal ( SIGQUIT, SIG_IGN);while

25、 (pid1=fork( ) = = -1);if (pid1 = =0) printf(“p1n”)signal (SIGUSR1, Int1);signal (16, SIG_IGN)pause ( );exit (0);elsewhile (pid2=fork( ) = = -1);if (pid2 = =0) printf(“p2n”)signal (SIGUSR2, Int1);signal (17, SIG_IGN)pause ( );exit (0);elseprintf (“parentn”);signal (SIGINT, IntDelete);waitpid( -1, &exitpid, 0);printf (“parent process is killed! n”);exit (0); 请大家将上述程序输入计算机后,执行并观察结果。由于忽略了中断与退出信号,程序会一直保持阻塞状态为无法退出。

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1