




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、实验一 进程管理一、实验目的:1.加深对进程概念的理解,明确进程和程序的区别;2.进一步认识并发执行的实质;3.分析进程争用资源的现象,学习解决进程互斥的方法;4.了解 Linux 系统中进程通信的基本原理;二、实验预备容:1.阅读 Linux 的 sched.h 源码文件,加深对进程管理概念的理解;2.阅读 Linux 的 fork() 源码文件,分析进程的创建过程;三、实验环境说明:1.此 实 验 采 用 的 是 Win7(32bit) 下 虚 拟 机 VMware-workstation-10.0.4build-2249910 ;2.ubuntu 版本 3.19.0 ;3.直接编写 c
2、文件在终端用命令行执行;4.虚拟机分配8G存中的1024M;5.虚拟机名称 knLinux ;6.ubuntu 用户名 kn ;四、实验容:1.进程的创建:a) 题目要求:编写一段程序, 使用系统调用 fork() 创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“ a”,子进程分别显示字符“ 试观察记录屏幕上的显示结果,并分析原因。b”和“ c”。b) 程序设计说明:一个父进程,两个子进程,分别输出显示a,b,c 。c) 源代码:4 projlx1#Include 2#Include sys/types3#Lnclude
3、4#Include 5#Include $tdlibhn6#in匚IudE 78int main()910pid_t pidl, pid2;1112while (pidl = forkO)=13if (pidl = 0)1415putcharC1b1);16exit(0);17181920whilt (pid2 = forkO) = -l)j21if (pid2 = 02223putchar(c1);24exit(0);25262728putcharta1);29exit(0);303132return 0;33d) 运行结果:rootubuntu:/hopie/kn# gcc Downloa
4、ds/proj 1.c - pl rootubuntu:/hone/kn# */pl arootubuntu:/horie/kn# be * / p 1 arootgubuntui/home/kn# cb./pl arootgubuntu:/home/kn# cb./pl abrootubuntu:/hone/kn# c./pl arootgubuntu:/home/kn# cb/pl arootgubuntu:/home/kn# cb*/pl arootgubunn# be./p1 arootubuntu:/hone/kn# cb*/pl arootgubuntui/home/kn# cb*
5、/pl arootubuntu:/horie/kn# cb_/pl araotulbuntu:/home/kn* cb./pl arootwbuntu:/home/kn# cb/pl arootubuntu:/home/kn# cb-/pl arootgulbuntu:/hone/kn* cb./pl aebrootipubuntu:/home/kn# ./pl drQQtwbuntu;/home/kn# be./pl arootubuntu:/home/kn# cb./pl arootubuntu:/home/kn# cb./pl arootubuntu:/home/kn# cb./pl d
6、roQtubuntu:/home/kn# bc/pl arootgubuntu:/home/kn# 匸b_/pl arootgubuntu/home/kng _cb|-r -f t i :-i t.i . -e. r :- / r: :;总氏*:紅汾律邂,熾电-i 1 I | :|r .i : d r i().r- j (. u ; u.j. t j : /i(.i -. 1二;_. . j.a;总痣诗養貉m泮电-,.yJ . T. . : . . It / . m J_-f :( 11.:.rf .i, n Ji-. -4 ( :.,:环总療遐述逐涝总L r t i :丨 一 r :-一 .
7、ye) 分析:由输出结果可知,运行结果不唯一,可以是abc,acb,bca等多种情况。 因为在程序中,并没有三个进程之间的同步措施, 所以父进程和子进程的 输出顺序是随机的。在试验次数足够大的情况下,6中顺序都有可能出现: abc, acb, bac, bca, cab, cba 。2. 进程的控制:a)修改已经编写的程序,将每个进程输出一个字符改为每个进程输出一句话,再观察程序执行时屏幕上出现的现象,并分析原因。i.程序设计说明:将第一个程序中输出字符的语句改为输出pare nt process和childprocessl &2 的语句。ii.源代码:4 1prQj21.c#includ:】
8、2#includ3finclud4tinclud5# nclude 6# -i(:78int maing10pid_t pidl, pid2;1112le (pidl = fork() =:L”13(pidl = 01415puts (Child Progress l!n*);16exlt(O);17181920while (pid2=fark() = -1);21 (pld2 = 0)2223putsCXhild Progress 2!n*;24exit(9);25262728sleep(4);29puts(Parent Progress InM);30exit(0);313233pturn
9、 0;34y运行结果:iii.rootubuntu:/home/knw gcc Downloads/proj21,c -o p21 rootubuntu:/hone/kn# */p21Child Progress 11Child Progress 2!Parent Progress!rootubuntu:/home/knff |iv.b)i.rootgubuntu:/hone/kn#Child Progress 21Child Progress 1JPa rent Progress 1 rootgubuntur/home/kn# |分析:发现在结果中,运行结果同第一个程序, 但是在一个进程输出
10、语句 的中途不会被打断,语句都是完整的。但是三条语句的先后顺序随机, 不能够确定。如果在程序中使用系统调用lockf ()来给每一个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。程序设计说明:在程序中加入lockf(1,1,0) 和lockf(1,0,0)语句用于加锁和去锁,实现进程之间的互斥。在程序中加入sleep()函数让父进程休息,多循环进行子进程的输出,可观察到加锁前后的差距。源代码:proj22 .c8int main()910pid_t pidl, pid2;11inti;1213le (pidl = fork) = -1);14(pidl = 0)1516lockf(l
11、| 1B 0);/Xock17(i = 0; i 4; i +)1819sleep(l);20putsCChild Progress l!n);2122lockfd, 0t 0); /unlock23exit(0);24252627while (pld2 = fork() = -1);28.1 (pid2 = 0)2930lockfflj lf 0); / - lack31for (i = 0; i 4; 1 +)3233sleep(i);34puts (Child Prog ress 2!n*);3536lockfdj0); u1l37exit0);383940Child Progress
12、1!Chtld Progress 2!Parent Progress 1rootubuntu:/hone/knff |iv.分析:通过上网查阅资料,了解到lockf(fileno(fp),F_LOCK,OL)函数中,file no(fp) 是要加锁的文件,其中 1则为标准输出流;F_LOCK为1 则加锁,0则解锁;0L为文件长度,0则为整个文件。由输出结果观 察到, 加锁的函数使得程序结果发生了变化。 在加锁后, 根据结果显 示,一个进程全部输出完毕后才交给另一个进程,表现为连续的 1 和连续的 2;而没有加锁的话,每一个进程输出完毕一次就随机选择 一个进程进行输入, 直到全部输出完毕, 导致
13、每一次输出的进程都是 随机的。从而看出 lockf() 对两个进程的输出表现出互斥作用。进程互斥是指两个或两个以上的进程, 不能同时进入关于同一组共 享变量的临界区域, 否则可能发生与时间有关的错误。而 lockf() 函 数作为监视锁, 对锁定的进程控制访问。 而在多次输出后, 三个进程 有可能同时进入同一组共享变量的临界区域,所以结果发生改变。3. 进程的软中断:a) 编写一段程序,使其实现进程的软中断通信;i. 题目要求:使用系统调用 fork() 创建两个子进程,再用系统调用 signal() 让父进程捕捉键盘上来的中断信号(即按 DEL键);当捕捉到中断信 号后, 父进程用系统调用
14、Kill() 向两个子进程发出信号, 子进程捕 捉到信号后分别输出下列信息后终止:Child Process 1 is killed by Parent!Child Process 2 is killed by Parent!父进程等待两个子进程终止后,输出如下的信息后终止:Parent Process is killedii. 程序设计说明:利用Del触发软中断SIGINT。要求在中断来临前,两个子进程都 处于等待状态,中断来临后立即响应。因此加入了my_wait() 和my_stop() 两个函数,并通过 flag 来实现子进程对中断信号的屏蔽。 父进程在杀死子进程后自杀,则引入SIGUS
15、R1和SIGUSR2两个信号,分别让两个子进程监听这个信号, 父进程收到中断信号后通过这两个 信号对子进程发出 kill 信号,再自杀。在程序的实现过程中,我们 需要父进程等待子进程终止后再自杀,则需要子进程引入signal 预置软中断处理函数, 等待父进程向他发出软中断信号, 而不是直接从 键盘上自行接受,再自行终止。而父进程使用 kill 向子进程发送软 中断信号,并且 wait 直到子进程处理中断,使用 exit(0) 终止执行 并且向父进程返回终止信息。 父进程一旦收到子进程发送来的终止信 息,则结束等待,终止自己的进程。iii. 源代码:12345678901234567890123
16、4567890123456111111111122222222223333333proj3.c# jljce # nelude # # ncl I” # ncl id ? # :1ide # I int flag;pid_t pidl, pid2;void my_wait(int q)(flag);void my_stop(int q)flag = 0;int main() signal(SIGINTf my_stop);while (pldl = forkO) = -1);if (pidl = 0) flag = 1;signal(SIGUSR1, my_stop);/set SIGUSR1
17、 to stop my_wait(0);/waitinglockf(lr lf 0);puts(HnChild Process 1 is killed by Parent!11); lockf(lr 0, 0);/unlocksleep(l); exit(0);37else3839(pid2 = fork) = -1);40(pid2 = e)4142flag = 1;43signal(SIGIJSR2, my_stop;44my_walt(0); f、#aiLinq4Slockf(l, lr 0);/lock46puts(HnChlld Process 2 is killed by Pare
18、nt!);47lockf(1,0;/unlock悶sleep(l);49exlt(e);505265retiirn0;67iv. 运行结果:rootgubuntu:/hame/kn gcc DownlDads/proj3,c -o p3 rootgubuntu :/home/knff Jp3ACChild Process 1 is killed by Parent 1Child Process 2 is killed by Parent!Parent Pro匸e呂百 is killed!rootfiubuntu:/hone/kn#v. 分析:ctrl+C信号并发传到所有进程中,而子进程中屏蔽掉
19、了中断信号,所以信号只发给了父进程,父进程终止,将kill信号发给两个子进程,从而显示出如上图的结果。b) 在上面的程序中增加语句sig nal(SIGINT, SIG-IGN) 和 sig nal(SIGQUIT,SIG-IGN),观察执行结果,并分析原因;i. 程序设计说明:在a)代码基础上加入以下两种信号:sig nal(SIGTINT, SIG_IGN);后台进程读中断信号,默认挂起;signal(SIGQUIT,SIG_IGN); 程序终止信号,默认操作写dump-core 文件ii.源代码:参照a)中源代码。运行结果:加上signal(SIGINT, SIG-IGN)后程序不再继续
20、进行:rootubuntu:/home/kn# gcc Downloads/proj3,c -o p3 rootubuntu: /horne/kn# + /p3ACChild Process 1 is killed by Parent!Child Process 2 is killed by Parent!加上 signal(SIGQUIT, SIG-IGN)后:rootubuntu: /hotne/kn# gcc Downloads/pro. c -o p3 rootubuntu:/home/kn# */p3 忙Child Process 2 ts killed by Parent IChi
21、ld Process 1 is killed by Parent!Parent Process Is killed I rootgubuntu:/home/kn# |加上 signal(SIGINT, SIG-IGN) 和 signal(SIGQUIT, SIG-IGN) 后:rootubuntu:/home/kn# gcc Downloads/proJ3.c -o p3 rootubuntu:/home/kn# */p3- 忙Child Process 2 vs killed by Parent!Child Process 1 ts killed by Parent!Parent Proce
22、ss Is killed rootubuntu:/home/kn# |iv. 分析:只加上signal(SIGINT, SIG-IGN),则父程序不再继续输出,程序 处于wait状态,因为在父进程收到信号时已默认为被杀死,程序停 留在 wait,不再继续进行,也没有父进程的输出。而当只加上 signal(SIGQUIT, SIG-IGN)时,输出结果不变。加上 signal(SIGINT, SIG-IGN)和signal(SIGQUIT,SIG-IGN)后,输出结果依旧不变。但是后两种情况的含义是不同的。当只加了 signal(SIGQUIT, SIG-IGN) 时,子进程收到键盘上的ctrl
23、+C中断信号从而被杀死,输出killed语句。而同时加上这两句话,屏蔽了从键盘上传来的中断信号,因此子进程接收到父进程传来的软中断信号,所以被杀死,输出killed语句。4.进程的管道通信:a)题目要求:编制一段程序,实现进程的管道通信。使用系统调用pipe()建立一条管道线;两个子进程P1和P2分别向管道各写一句话:Child 1 is sending a message!Child 2 is sending a message!而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。要求父进程先接收子进程 P1发来的消息,然后再接收子进程P2发来的消息b) 程序设计说明:两个子进程分别
24、向管道写一句话,为了避免两个进程抢占管道,利用一个sleep()函数将两个进程有效的时间区分开来,并且在第一个进程写进数据时,对管道进行加锁,写完后解锁,第二个进程继续写数据,以此避免冲突的产生。而父进程则在子进程全部进行完毕后再执行。c) 源代码:9int PIPE_MAX -;10const int RW_MAX = 0x40;/r/w buffer max size11int main)12 0);/loc34sprintf(wbf Child 2 is sending a message!n);35write (river 1 rRW_MAX);36lockf(riverlj, 0*
25、0);J37exit(0);39394041wait(NULL);/wait pl42read(river0f rb, RW_MAX);43prlntfCsXn-*, rb);44wait (NULL);Z/ait p245read(river0, rb, RW_MAX);46prlntf(Wsn,l( rb);47exit(0);484950r- nliiina 11fiihEn Xd) 运行结果:rootubuntu:/hoME/kn# gcc Downlodds/praj4u -o p4 rootgubuntu:/home/kn# /p4Child 1 ts sending a ness
26、agelChild 2 is sending a nessagelrootubuntu:/home/kn# |e) 分析:若是多次进行管道写入,并想保证一个进程完整运行,则必须加锁;若单次,不一定需要lockf(),因为一个标准输出流一定会完整的写完不 被中断,然后再进行其他操作。在管道通信中,系统调用pipe()函数初始化一个二元组作为管道,1为出,0为进,以此来保证管道通信不发生 冲突。五、思考:1. 系统是怎样创建流程的?操作系统在创建流程时,首先申请空白的PCB(进程控制块),再为新进程分派资源,然后初始化 PCB,最终将新进程插入就绪队列中。而在我们编程的 过程中,系统通过调用for
27、k()函数来创建进程。而当一个进程中调用了fork()函数时,则系统会为这个进程创建一个子进程。这个子进程和父进程不同的地方只有他的进程 ID,其他部分都一样。也就是说新进程通过克隆老进程或是 当前进程来创建。其中系统调用fork()或clone()函数可以创建新任务,复制 发生在核心状态下地核心中。复制完成后,Linux允许两个进程共享资源而不是复制各自的拷贝(包括文件、信号处理过程和虚拟存)。而在创建后,先执行父进程还是子进程则取决于核的调度算法。子进程被 创建后,父子进程相互竞争系统的资源,并行执行。若想子进程先继续执行, 则需要父进程阻塞至子进程完成任务,即用wait()系统调用来完成
28、。2. 可执行文件加载时进行了哪些处理?在编译执行源代码的过程中,由程序,到编译预处理,到编译,到优化程 序,到汇编程序,到程序,最后到可执行文件。在加载可执行文件时首先操作 系统应该判断该文件是否为一个合法的执行文件,若是则按照段表中的指示为可执行文件分配地址空间。在加载文件的过程中, 主要是需要加载程序段和数据段到存,并且进行外部定义符号的重定位。任何一个可执行文件, 启动时都需要调用 Ntdll.dll 中的 NtCreateProcess()函数。3. 当首次调用新创建进程时,其入口在哪里?在进程队列ready的状态下,由离自己最近的父进程执行调度,即入口在最近的父进程处,是fork(
29、)之后的语句。4. 进程通信有什么特点?linux下进程间通信的几种主要方式:管道(Pipe )及有名管道(named pipe):管道可用于具有亲缘关系进程间的 通信,有名管道克服了管道没有名字的限制, 因此,除具有管道所具有的功能外, 它还允许无亲缘关系进程间的通信;信号(Signal ):信号是比较复杂的通信方式,用于通知接受进程有某种事件 发生,除了用于进程间通信外,进程还可以发送信号给进程本身;linux 除了支持Unix早期信号语义函数 sigal夕卜,还支持语义符合 Posix.1标准的信号函数 sigaction(实际上,该函数是基于BSD的,BSD为了实现可靠信号机制,又能够统一对外接口,用 sigaction 函数重新实现了 signal函数);报文(Message)队列(消息队列):消息队列是消息的表,包括Posix消息队列system V消息队列。有足够权限的进程可以向队列中添加消息,被赋予读权 限的进程则可以读走队列中的消息。消息队列克服了信号承载信息量少,管道只 能承载无格式字节流以及缓冲区大小受限等缺点。共享存:使得多个进程可以访问同一块存空间,是最快的可用IPC形式。是针对其他通信机制运行效率较低而设计的。往往与其它通信机制,如信号量结合使 用,来达到进程间的同步及互斥。信号量(
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 徐州月星前期策划
- 江西工业工程职业技术学院2023年单招职业技能测试试卷及答案
- (高清版)DB12∕T 510-2014 地理标志产品 黄花山核桃
- 英语培训课件范文
- 项目招商手册委托设计制作合同(2025年版)
- 劳动合同不续签的通知(2025年版)
- 2025年年平板显示合作协议书
- 二零二五年度劳动合同法企业劳动法律培训与实施合同
- 欠款合同国家(2025年版)
- 2025年度计件工劳动合同(新能源电池组装)
- GB/T 625-2024化学试剂硫酸
- 多重耐药感染的集束化护理
- 对外贸易操作流程作业指导书
- 江苏省历年中考语文现代文阅读之非连续性文本阅读39篇(含答案)(2003-2023)
- 2024住院患者静脉血栓栓塞症预防护理与管理专家共识要点(全文)
- 金蝶云星空标准解决方案
- 缠论-简单就是美
- 2023年浙江宁波文旅会展集团有限公司招聘考试真题
- 异地就医备案的个人承诺书
- 南京市江宁区竹山中学2023-2024学年七年级下学期月考数学试题【带答案】
- QCT1177-2022汽车空调用冷凝器
评论
0/150
提交评论