欢迎来到课桌文档! | 帮助中心 课桌文档-建筑工程资料库
课桌文档
全部分类
  • 党建之窗>
  • 感悟体会>
  • 百家争鸣>
  • 教育整顿>
  • 文笔提升>
  • 热门分类>
  • 计划总结>
  • 致辞演讲>
  • 在线阅读>
  • ImageVerifierCode 换一换
    首页 课桌文档 > 资源分类 > DOCX文档下载  

    使用fork创建进程.docx

    • 资源ID:86111       资源大小:74.19KB        全文页数:16页
    • 资源格式: DOCX        下载积分:10金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要10金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    使用fork创建进程.docx

    使用fork创建进程L实验目的(1)理解LinUX实现系统调用的机制;(2)理解并掌握fork系统调用创建新进程的过程和原理;(3)掌握Vi(vim)、GCC和GDB的使用。2 .实验内容(1)通过编程验证fork函数的实现机制,并理解写时拷贝COW的意义;(2)使用fork和exec函数创建新进程。3 .实验方法(实验步骤)实验二步骤:第一步:双击打开进入IinUX的终端,用Vi新建一个Del_Sleep.C的文件第二步:创建成功之后,输入“a”或"o”或"i”进行插入编辑写入模式第三步:开始写我们的代码第四步:代码编辑完成之后,按“Esc”间退出编辑模式第五步:输入“:wq”对我们刚才编辑的代码进行保存退出第六步:输入“gccDel_Sleep.c-oDel_Sleep”命令运行代码的编译成可执行文件第七步:然后输入“./a.out”或者"./Del_Sleep"进行代码的运行,得到我们程序的运行结果实验三步骤:第一步:双击打开进入IinUX的终端,用Vi新建一个Three_Fork.c的文件第二步:创建成功之后,输入“a”或"o”或"i”进行插入编辑写入模式第三步:开始写我们的代码第四步:代码编辑完成之后,按“Esc”间退出编辑模式第五步:输入“:wq”对我们刚才编辑的代码进行保存退出第六步:输入“gccThree_Fork.c-oThree_Fork,命令运行代码的编译成可执行文件第七步:然后输入“/a.out”或者”./Three_Fork"进行代码的运行,这时候就可以得到我们程序的结果实验四步骤:第一步:双击打开进入IirIUX的终端,用Vi新建一个two_before.c的文件第二步:创建成功之后,输入“a”或"o”或"i”进行插入编辑写入模式第三步:开始写我们的代码第四步:代码编辑完成之后,按“Esc”间退出编辑模式第五步:输入“:wq”对我们刚才编辑的代码进行保存退出第六步:输入“gcctwobefore.c-Otwo_before”命令运行代码的编译成可执行文件第七步:然后输入“./two_before>ou.tst"进行代码的运行,第八步:继续输入"catou.tst"这时候就可以查看我们程序的结果4 .实验过程(源代码、配置清单必须带注释)注释:源码中出现的定义Pid为进程号,PPid为父进程号,getppid为获取父进程id,getpid为获取子进程id,SleeP为睡眠时钟,fork函数为一次调用,返回两个值,子进程返回0,父进程返回子进程id标记,出错返回-1,exec函数把程序(保存在磁盘某个目录中的可执行文件)读入内存并执行,Exec函数不创建进程,而是用一个新的程序替换当前进程的代码段、数据段和堆栈。execve(,7binlszz,arg,NULL)为使用exec函数执行一个新的程序(binls)char*arg3=,7binls,-,NULL)为定义一个字符串数组,最后一个数组元素为null1使用GCC调试C程序(预处理、编译、汇编、链接)预处理:对xx.c中的预处理命令进行处理,生成一个中间文件XX.iOrootubuntu:Rou文件(F)编辑(E)查看(V)线端(T)帮助(H)rootubuntu:#cdRourootubuntu:/Rou#IsThreeFork.*ThreeFork.crootubuntu:*/Rou#gccThreeFork.c-oThreeFork.iroottaubuntu:-/Rou#IsThreeFork.*ThreeFork.cThreeFork.iroot(Qubuntu:-/Rou#编译:对中间文件xxi进行编译,生成ASCn的汇编语言文件XX.S©rootubuntu:Rou文件(F)Si»(E)Sfi(V)«a(T)帮助(H)IrOOtiIbUntu:#cdRourootubuntu:/Rou#ISThreeFork.*IThreeFork.cThree_Fork.irootubuntu:/Rou#gccThreeFork.c-oThreeFork.srootubuntu:/Rou#LSThreeFork.*I程序“LS”尚未安装。您可以便用以下命令安装:apt-getinstallSlrootubuntu:-/Rou#IsThreeFork.*IThreeFork.cThree_Fork.iThree_Fork.srootubuntu:/Rou#汇编:把汇编文件XX.S转换成可重定位的目标文件XX.OCQrootubuntu:-ZRou文件(F)媚辑(E)查看(V)帮助(H)rootubuntu:-#cdRouroottaubuntu:-/Rou#IsThreeFork.*ThreeFork.cThree_Fork.iThree_Fork.sroot(aubuntu:-/Rou#gccThreeFork.c-oThreeFork.oroot(aubuntu:-/Rou#IsThreeFork.*ThreeFork.cThreeFork.iThree_Fork.oThree_Fork.srootubuntu:-/Rou#链接:把若干个可重定位的目标文件以及共享的库文件汇集成一个可执行的目标文件©.root(g)ubuntu:Rou文件(F)编辑(E)Sfi(V)终端(T)帮助(H)rootubuntu:#cdRourootubuntu:-/Rou#IsThreeFork.*ThreeFork.cThreeFork.iThreeFork.oThreeFork.sroot(3ubuntu:-/Rou#gccThreeFork.c-oThreeForkrootubuntu:-/Rou#./ThreeForkbeforeforkingThisischildprocess.pid=6946,ppid=6945Thisischildprocess.pid=6947fppid=6946Thisischildprocess.pid=6948,ppid=6947使用GDB调试C程序(quit退出调试)OCQroot(g>ubuntu:-/Rou文件(F)编辑(E)查看(V)终端Cr)用助(H)rootubuntu:-#cdRourootubuntu:-/Rou#gcc-gThreeFork.c-oThreeForkrootQubuntu:/Rou#gdb-qThreeForkReadingsymbolsfromrootRouThreeFork.done.(gdb)2Exec函数的使用题1:使用exec函数执行一个新的程序(binls)源码0rootubuntu:-/Rou文由F)Htt(E)S(V)HiS(T)帮助(川#include-#include-#include*inmain(intargctchar*argv)pidtpid;int-i=;,getpid(),getppid(););char*arg=,printf(pid=fork();if(pid<)(printf()elseif(pid=)printf(if(execve(printf(exit();elsesleep();printf(dn,getpid();)return;)0Qrootubuntu:*Rou文件(F)SItt(E)fifi(V)tta)帮助(H)rootubuntu:/Rou#gccforkexec.crootubuntu:/Rou#./a.outiBeforeforking.Thisischildprocess.pid=6653,ppid=6652total96-rwxrw-rw-1rootroot1129Oct1322:042.c叩-rw-r-r-1rootroot761Oct1322:144.ci-rw-r-r-1rootroot805Oct1322:2944.c-rw-r-r-1rootroot2109Oct1322:3355.c-rwxr-xr-x1rootroot4845Oct1401:44DelSleep-rwr-r-1rootroot395Oct1323:31DelSleep.c-rwr-r-1rootroot447Sep2900:01ExecTree.c-rwxr-xr-x1rootroot4955Oct1323:39ForkThree-rw-r-r-1rootroot439Oct1323:38FOrklThree.c-rw-r-r-1rootroot416Sep2900:17ForkThreeDeisleep.c-rw-r-r-1rootroot924Oct1401:37ThreeFork.c-nxrv-n-1rootroot885Oct1418:15ThreeforkTree.c-rwxr-xr-x1rootroot524Oct1418:55a.out-rwxrw-rw-1rootroot579Oct1418:55fork_exec.c-rw-r-r-1rootroot149Oct1401:40ou.tst-rw-r-r-1rootroot379Octl20:41pstreetest.c-rw-r-r-1rootroot91Octl21:36tree.cfr'c,_1-cc+IUAGCi14crr+-一-3Fork函数的使用题2:去掉sleep源码Orootubuntu:*Rou文件(F)ttWE)fifl(V)终翻T)WSI(H)Itinclude<systypes.h>main(ntargc,char*argv)(pidtpid;printf(pid=fork();if(pid<)();printf()elseif(pid=);printf()else,getpid(),getppid();printf()return;),getpid();©Grootubuntu:*Rou文件(F)煽Ifl(E)杳看(V)终造(T)帮助(H)rootubuntu:#cdRourootubuntu:/Rou#gccDelSleep.c-oDelSleeproot(aubuntu:/Rou#./DelSleepbeforeforkingThisisparentprocess.pid=6631root0ubuntu:'/Rou#Thisischildprocess.pid=6632,ppid=1题3:fork的三次调用源码©rootubuntu:-/Rou文件(F)a(E)fi«(v)()常助(H)ficlude<sinclude<unistd.h>winclude<systypes.h>intmain(intargc,char*argv)pidtpid;printf(.);pid=fork();net,<;-if(pid<)(printf(ln);)elseif(pid=)(printf(:.r:Jn,getpid(),getppid();else(sleep();printf(dn,getpid();Ipid=fork();if(pid<)printf(n);)elseif(pid=)printf(cin,getpid(),getppid();)else(sleep();printf(pcrentprocess二Cn,getpid();)/threetimespid=fork();if(pid<)(printf(1n);)elseif(pid=)printf(,getpid(),getppid();)elsesleep();printf(dn,getpid();return;运行结果O*Qrootubuntu:Rou文件(F)编辑(E)fi(V)ita(T)朗助(H)rootubuntu:"#cdRourootubuntu:/Rou#gccThreeFork.croot(aubuntu:/Rou#./a.outbeforeforkingThisischildprocess.pid=6500,ppid=6499Thisischildprocess.pid=65l,ppid=650Thisischildprocess.pid=652,ppid=65lIThisisperentprocess.pid=6499Thisisperentprocess.pid=650Thisisperentprocess.pid=65lThisischildprocess.pid=653,ppid=6499Thisischildprocess.pid=654,ppid=65Thisischildprocess.pid=655,ppid=653Thisisperentprocess.pid=6499Thisisperentprocess.pid=6500Thisisperentprocess.pid=653Thisischildprocess.pid=656,ppid=6499Thisisperentprocess.pid=6499root(3ubuntu:/Rou#进程树(父进程与子进程关系)源码©Grootubuntu:-Rou文件(F)编殂(E)查看(V)线端(T)帮助(H)Treefork(ispstree)(intpid;pldfork();if(pld<)(printf();)elseif(pid*)else<sleep();ppid=getpid().pstreepid;PStree_PidTOrk();if(pstreepid<)printf();else(lf(pstree_pld=)chea(:sprintf(a.ppd);char*arg(.,a,;if(execve(.arg,)<)(printf();exit();printf()elsesleep();1)ain().i:Treefork();printf();Irt1,j;for(i=:i<1+»(Treefork();sleep();)return;COQrootubuntu:Rou文件(F)编辑(E)有看(V)终选(T)帮助(H)FOotiIbUntu:TCdRouIrootubuntu:-/Rou#gccThreefork_Tree.crootubuntu:-/Rou#./a.outa.out(7172)-a.out(7173)'-pstree(7174)a.out(7173)-a.out(7175)'-pstree(7176)a.out(7172)-a.out(7173)-a.out(7175)Ipstree(7176)-a.out(7177)Ipstree(7174)-pstree(7178)a.out(7175)-a.out(7179)-pstree(718)a.out(7177)-a.out(7181)-pstree(7183)a.out(7173)-+-a.out(7175)-+-a.out(7179)I'-pstree(718)-a.out(7182)I-pstree(7176),-pstree(7184)a.out(7172)-+-a.out(7173)-+-a.out(7175)-+-a.out(7179)II,-pstree(718)-a.out(7182)-pstree(7176)I-pstree(7184)-a.out(7177)-a.out(7181)I-stree(7183)-a.out(7185)I-pstree(7174)-pstree(7178)-pstree(7186)rootUbUntU:Rouf题4:Cat命令查看可执行文件源码文件(F)»M(E)fi*(V)»»(T)ffi0(H)/include<stdio.h>#include<unistd.h>#include<systypes.h>mtmain(intargc,char*argv()pidtpid;printf(1);pid=fork();if(pid<)(printf(l);elseif(pid=)printf(外,getpid(),getpid();elsesleep();printf(sdn,getpid();return;)运行结果Grootubuntu:-/RouI文件(F)编辑(E)查看(V)终端(T)帮助(H)rootubuntu:#cdRourootubuntu:-/Rou#gcctwobefore.c-otwobeforerootubuntu:/Rou#.twobefore>ou.tstrootubuntu:-/Rou#catou.tst(beforeforkingThisischildprocess.pid=6599,ppid=6598IbeforeforkingThisispartentprocess.pid=6598irootubuntu:/Rou#5.思考题题2:去掉父进程的Sleep,会出现什么结果?如果父进程先运行,子进程后运行,为什么?eGrootubuntu:*Rou文件(F)埃Sa(E)杳看(V)终造(T)帮助(H)rootubuntu:#cdRourootQubuntu:-/Rou#gccDel_Sleep.c-oDelSleeproot(aubuntu:/Rou#./DelSleepbeforeforkingThisisparentprocess.pid=6631root0ubuntu:'/Rou#Thisischildprocess.pid=6632,ppid=1答:去掉父进程的Sleep,会发现只有父进程彻底执行完之后才会执行子进程。使用SleeP是为了防止父进程先退出,从而产生异常。一般来说,fork之后是父进程先执行还是子进程先执行是不确定的,这取决于内核使用的调度算法。这是因为对于进程的创建而言,子进程的形成需要很多的时间来复制父进程的大部分资源,代码段,数据段,创建Pid等,所以在这个时间里父进程会开始执行的,导致我们总是会直观的看到父进程总是先执行。而且在负荷非常重的系统中,谁先得到调度执行是由操作系统在运行时决定的,而且每次运行的结果也不一样。题3:写一个main()函数,执行3个fork,fork,fork,会产生几个子进程?根据进程完善代码,并画出进程树0Qrootubuntu:-/Rou文件F)编辑(E)Sfi(V)Jta(T)帮助(H)Toot(3ubuntu:#cdRourootubuntu:/Rou#gccThreeFork.Crootubuntu:/Rou#./a.outbeforeforkingThisischildprocess.pid=650,ppid=6499Thisischildprocess.pid=65llppid=650Thisischildprocess.pid=65021ppid=6501Thisisperentprocess.pid=6499Thisisperentprocess.pid=6500Thisisperentprocess.pid=65lThisischildprocess.pid=653,ppid=6499Thisischildprocess.pid=654,ppid=65Thisischildprocess.pid=655,ppid=6503Thisisperentprocess.pid=6499Thisisperentprocess.pid=650Thisisperentprocess.pid=6503Thisischildprocess.pid=656,ppid=6499Thisisperentprocess.pid=6499root(3ubuntu:-/Rou#答:会产生8个进程进程树:题4:运行a./forkdemo>ou.tst”,用cat查看"ou.tst运行结果,出现两个beforeforking,为什么?Orootubuntu:Rou文件(F)编辑(E)M(V)终端(T)帮助(H)rootubuntu:*#cdRou*root0ubutu:/Rou#gcctwobefore.c-otwobeforeroot(3ubuntu:/Rou#.twobefore>ou.tstroot(aubuntu:-/Rou#catou.tstbeforeforkingThisischildprocess.pid=6599,ppid=6598beforeforkingThisispartentprocess.pid=6598rootubuntu:/Rou#答:在LinUX下,这种情况主要和Printf的缓冲机制有关。运行Printf,字符串内容会被放到缓冲区里,当程序运行到fork时,缓冲区里面的内容就会被子进程复制过去,因此在子进程缓冲区里面也就有了相应的字符串,这时,父进程和子进程都会有该相应的字符串内容,所以最终我们会看到beforeforking被打印两次6.实验体会答:在实验过程中,一直在考虑调用运行fork时会产生什么情况的父进程和子进程,两者处于什么关系,而且在调用fork产生进程时,会发现每次运行调用fork产生的进程中父进程和子进程都不一样,并且fork函数的就是调用一次,返回两次,在父进程中调用一次,在父进程和子进程中各返回一次。在这次实验中,我理解了在IimIX环境下通过调用fork和exec产生进程的原理、父进程与子进程的关系、Printf的缓冲机制、以及SIeeP在程序中的作用。虽然在这次实验中由于需要对这些知识进行反复梳理与理解,推导及证论上而花了很多时间,但也让我彻底明白了fork,exec,Printf及SIeeP的工作机制,理解LinUX实现系统调用的机制、Vi(Vin1)、gcc和gdb的使用和写时拷贝COW的作用,同时并掌握fork系统调用创建新进程的过程和原理,收获很大。

    注意事项

    本文(使用fork创建进程.docx)为本站会员(夺命阿水)主动上传,课桌文档仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知课桌文档(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-1

    经营许可证:宁B2-20210002

    宁公网安备 64010402000986号

    课桌文档
    收起
    展开