实验二 Linux 进程实验
姓名:段叶叶
班级:信息1302 学号:07131052
地点:东区实验室FF109 时间:2014年10月13日星期一 成绩:
一、实验内容
1. 创建进程的系统调用fork(); 2. 创建进程的系统调用vfork(); 3. 执行新程序的系统调用exec();
4. 等待进程结束的系统调用wait()或waitpid()。 前三题必做 ,最后一题选做。 二、实验目的 熟悉进程的系统调用。 三、实验环境
登陆Linux虚拟机,进入Linux shell, 提示符为 $,表示普通用户提示符。 四、实验题目
1. 【题目】: 编写程序forkgrandchild.c,用来创建孙子进程。
【要求】:在读懂程序forktest.c的基础上,编写程序
forkgrandchild.c(forkgrandchild.c创建在用户名(如wm)目录下的process目录下),所创建的程序forkgrandchild.c可实现创建孙子进程,并显示孙子进程的pid,其父进程的pid,forkgrandchild.c要求可读性好,用户界面友好。
【预备知识】: 1) Linux进程状态
? 运行状态:程序正在运行或在运行队列中等待运行。
? 可中断等待状态:进程正在等待某个事件完成,等待过程可被信号或定时器
唤醒。
? 不可中断等待状态:进程正在等待某个事件完成,不可被信号或定时器唤醒,
必须等待事件的发生,才可唤醒。
? 僵死状态:进程已终止,但进程描述符依然存在,直到父进程调动wait()函
数后释放。
? 停止状态:进程因收到SIGSTOP SIGSTP SIGTIN SIGTOU信号后停止运行
或该进程正在被跟踪(调式程序时)。
2) ps命令
? ps命令可查看进程的当前状态。 ? 如 ps aux(相关命令参数自学) ? 对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之后是父还是子进程先运行是不确定的,这取决于内核所使用的调度算法,一般是交替执行,使进程享有同等执行权。
forktest.c 源代码 #include
【问题】:
1) 解释stdio.h、unistd.h、sys/types.h头文件的作用? 2) getpid()、getppid()、fork()的功能是什么? 3) 写出forkgrandchild.c的源代码。
(1)a.stdio.h头文件的作用是:就是指“standard input&output\ 就是说标准输入输出头文件。所以,用到标准输入输出函数时,就要 调用这个头文件! 原程序为:
case 0 : printf(\curpid is %d,parentpid is %d\\n\pid2=fork(pid1); switch(pid2) { case 0: printf(\parentpid is %d\\n\ break; case -1: printf(\creation failed\\n\ break; default: printf(\process is running ,grandchildpid is %d,parentpid is %d\\n\,getpid()); break; } case -1: printf(\creation failed\\n\ break; default: printf(\process is running ,childpid is %d,parentpid is %d\\n\,getpid()); break; } exit(0); } 2. 【题目】:diffork.c的创建
【要求】:
上机实现下面diffork.c的运行,体会fork()和vfork()的区别。 【预备知识】:
1) fork()和vfork()的区别
? fork()和vfork()都是调用一次,返回值两次。
? fork()创建一子进程时,子进程只是完全复制父进程资源,这样得到的子
进程独立于父进程,具有良好的并发性,但开销较大,有时是不需要的,比如fork一个进程后,立即调用exec执行另一个应用程序,那么fork过程中子进程对父进程地址空间的复制将是一个多余的过程,而vfork()创建的
子进程共享父进程的地址空间,不拷贝父进程的地址空间,这大大减少了系统开销。
? vfork()保证子进程先运行,当它调用exec()或exit之后,父进程才可能
被调度。 diffork.c 源代码 #include
【注意】:
将diffork.c中的sleep()的参数增大些,开启另一个终端,在该终端下输入ps aux查看父子进程的信息,特别是状态信息。 【结果】: