操作系统B-上机实验-进程.doc_第1页
操作系统B-上机实验-进程.doc_第2页
操作系统B-上机实验-进程.doc_第3页
操作系统B-上机实验-进程.doc_第4页
操作系统B-上机实验-进程.doc_第5页
已阅读5页,还剩4页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验二 Linux 进程实验一、 实验内容l 创建进程的系统调用fork();l 创建进程的系统调用vfork();l 执行新程序的系统调用exec();l 等待进程结束的系统调用wait()或waitpid()。二、 实验目的熟悉进程的系统调用。三、 实验环境登陆Linux虚拟机,进入Linux shell, 提示符为 $,表示普通用户提示符。四、 实验题目A 【题目】:创建孙子进程forkgrandchild.c【要求】:在读懂fork.c的基础上,创建forkgrandchild.c(forkgrandchild.c创建在用户名(如wc)目录下的process目录下),所创建的forkgrandchild.c可实现创建孙子进程,并显示孙子进程的pid,其父进程的pid,forkgrandchild.c要求可读性好,用户界面友好。【预备知识】:1. Linux进程状态l 运行状态:程序正在运行或在运行队列中等待运行。l 可中断等待状态:进程正在等待某个事件完成,等待过程可被信号或定时器唤醒。l 不可中断等待状态:进程正在等待某个事件完成,不可被信号或定时器唤醒,必须等待事件的发生,才可唤醒。l 僵死状态:进程已终止,但进程描述符依然存在,直到父进程调动wait()函数后释放。l 停止状态:进程因收到SIGSTOP SIGSTP SIGTIN SIGTOU信号后停止运行或该进程正在被跟踪(调式程序时)。2. ps命令l ps命令可查看进程的当前状态。l 如 ps aux(相关命令参数自学)l 对ps命令结果字符的解释(高优先级进程)、N(低优先级进程)、L(内存锁页,即页不可被换出内存)、s(该进程为会话首进程)、l(多线程进程)、+(进程位于前台进程组)、R(运行状态)、Z(僵死状态)、D(不可中断等待状态)、S(可中断等待状态)、T(停止状态)。3. fork()函数fork()是创建一个新进程的唯一方法,子进程可以继承其父进程几乎所有的资源。在命令行下使用man 2 fork 可获得该函数的函数声明。fork()有两个返回值。成功调用fork后,当前进程实际上已经分裂为两个进程,一个是原来的父进程,另一个是刚刚创建的子进程。父子进程在调用fork地方分开,一个是父进程调用fork的返回值,返回值为刚刚创建的子进程的pid;另一个是子进程中fork函数的返回值,为0。fork返回两次的前提是进程创建成功,若失败返回为-1。用返回值可区分父子进程。fork之后是父还是子进程先运行是不确定的,这取决于内核所使用的调度算法,一般是交替执行,使进程享有同等执行权。fork.c 源代码#include #include #include int main(void) pid_t pid; printf(process creation studyn); pid=fork( ); switch(pid) case 0 : printf(child process is running,curpid is %d,parentpid is %dn,pid,getppid(); break; case -1: printf(process creation failedn); break; default: printf(parent process is running ,childpid is %d,parentpid is %dn,pid ,getpid(); break; exit(0); 【问题】: 1、 解释stdio.h、unistd.h、sys/types.h头文件的作用?2、 getpid()、getppid()、fork()的功能是什么?3、 写出forkgrandchild.c的源代码。1、 stdio.h 标准I/O库;unistd.h 符号常数;sys/types.h 原系统数据类型2、 getpid() 返回当前进程标识;getppid() 返回父进程标识;fork()是创建一个新进程的唯一方法,子进程可以继承其父进程几乎所有的资源。fork()有两个返回值。成功调用fork后,当前进程实际上已经分裂为两个进程,一个是原来的父进程,另一个是刚刚创建的子进程。3、源代码:#include #include #include int main(void) pid_t p1,p2; printf(process creation studyn); p1=fork( ); switch(p1) case 0 : printf(child process is running,curp1 is %d,parentpid is %dn,p1,getppid(); p2=fork( ); switch(p2) case 0 : printf(grandchild process is running,curp2 is %d,parentpid is %dn,p2,getppid();break; case -1: printf(process creation failedn); break; default: printf(parent process is running ,grandchildpid is %d,parentpid is %dn,p2,getpid(); break; exit(0); break; case -1: printf(process creation failedn); break; default: printf(parent process is running ,childpid is %d,parentpid is %dn,p1,getpid(); break; exit(0); B 【题目】:diffork.c的创建【要求】:上机实现下面diffork.c的运行,体会fork()和vfork()的区别。【预备知识】:1、 fork()和vfork()的区别l fork()和vfork()都是调用一次,返回值两次。l fork()创建一子进程时,子进程只是完全复制父进程资源,这样得到的子进程独立于父进程,具有良好的并发性,但开销较大,有时是不需要的,比如fork一个进程后,立即调用exec执行另一个应用程序,那么fork过程中子进程对父进程地址空间的复制将是一个多余的过程,而vfork()创建的子进程共享父进程的地址空间,不拷贝父进程的地址空间,这大大减少了系统开销。l vfork()保证子进程先运行,当它调用exec()或exit之后,父进程才可能被调度。diffork.c 源代码#include #include #include int globvar=5;int main(void) pid_t pid; int var=1 , i; printf(fork is diffirent with vforkn); /* pid=fork();*/ pid=vfork(); switch(pid) case 0: i=3; while(i-0) printf(child process is runningn); globvar+; var+; sleep(15); printf(child is globvar=%d,var=%dn,globvar,var); break; case -1: printf(parent creation failedn); exit(0); default : i=5; while(i-0) printf(parent process is runningn); globvar+; var+; sleep(5); printf(parent is globvar=%d,var=%dn,globvar,var); exit(0); 【注意】: 1、 将diffork.c中的sleep()的参数增大些,使用putty开启另一个会话,登录Linux,在该终端下输入ps aux查看父子进程的信息,特别是状态信息。【问题】:1、 写出输出结果。fork is different with vforkparent process is runningparent process is runningparent process is runningparent process is runningparent process is runningparent is globvar=10,var=6USER PID %MEM VSI RSS TTY STAT START TIME COMMAND115 2538 0.0 1824 248 pts/0 D+ 23:02 0:00 ./diffork115 2539 0.0 1824 248 pts/0 S+ 23:02 0:00 ./diffork C 【题目】:执行新程序的系统调用exec()【要求】:上机实现下面processimage.c和execve.c的运行,体会执行新程序的系统调用。【预备知识】:1、 使用fork或vfork创建子进程后,子进程通常会调用exec函数来执行另外一个程序,系统调用exec用于执行一个可执行程序以代替当前进程的执行映像。2、 exec调用并没有生成新进程,一个进程一旦调用exec函数,它本身就死亡了。系统把代码段替换成新的程序的代码,废弃原有的数据段和堆栈段,并为新进程分配新的数据段和堆栈段,唯一保留是pid,即,对系统而言,还是同一个进程,不过执行的已经是另一个程序了。3、 exec函数族有6种不同的调用形似,如execv()、execve()等,它们声明在unistd.h中。processimage.c 源代码#include #include #include int main(int argc,char * argv,char *environ) int i; printf(i am a process image!n); printf(my pid=%d,parentpid=%dn,getpid(),getppid(); printf(uid=%d,gid=%dn,getuid(),getgid(); for(i=0;iargc;i+) printf(argv%d:%sn,i,argvi);execve.c 源代码#include #include #include int main(int argc,char *argv,char *environ) pid_t pid; int stat_val; printf(exec example!n); pid=fork(); switch(pid) case -1: perror(process creation failedn); exit(1); case 0: printf(child process is runningn); printf(my pid=%d,parentpid=%dn,getpid(),getppid(); printf(uid=%d,gid=%dn,getuid(),getgid(); execve(processimage,argv,environ); printf(process never go to here!n); exit(0); default: printf(parent process is runningn); break; wait(&stat_val); exit(0);【注意】: 1、 理解带参数的main()函数。2、 在Linux命令行下,使用man execve 获取该函数的帮助。【问题】:1、 先编译链接processimage.c,再编译链接execve.c, 查看运行结果,结果说明了什么?i am a process image! my pid=2951,parentpid=2885uid=115,gid=126argv0:./processimageparent process is runningchild process is runningmy pid=3032,parentpid=3031 uid=115,gid=126i am a process image! my pid=3032,parentpid=3031uid=115,gid=126argv0:./execveexec调用并没有生成新进程,一个进程一旦调用exec函数,它本身就死亡了。系统把代码段替换成新的程序的代码,废弃原有的数据段和堆栈段,并为新进程分配新的数据段和堆栈段,唯一保留是pid,即,对系统而言,还是同一个进程,不过执行的已经是另一个程序了。 D 【题目】:等待进程结束的系统调用wait()或waitpid()。【要求】:上机实现下面wait.c的运行,体会等待进程结束wait()系统调用。【预备知识】:子进程先于父进程终止,而父进程又没有调用wait函数等待子进程结束,子进程进入僵死状态,并会一直保持下去除非重启。子进程进入僵死状态时,内核只保存该进程的一些必要信息以备父进程所需。此时子进程始终占用着资源,同时也减少了系统可创建的最大进程数。如果子进程先于父进程终止,且父进程调用了wait或waitpid函数,则父进程会等待子进程结束,就不会使子进程变为僵尸进程。wait.c 源代码#include #include #include #include int main() pid_t pid; char *msg; int k; int exit_code; printf(study how to get exit coden); pid=fork(); switch(pid) case 0: msg=child process is running; k=5; exit_code=37; break; case -1: perror (process creation failedn); exit(1); default: exit_code=0; break; if (pid!=0) int stat_val; pid_t child_pid; child_pid=wait(&stat_val); printf(child process has exited,pid=%dn,child_pid); if (WIFEXITED(stat_val) printf(child exited with code %dn,WEXITSTATUS(stat_val); else p

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论