好文档 - 专业文书写作范文服务资料分享网站

操作系统B2-上机实验-进程 

天下 分享 时间: 加入收藏 我要投稿 点赞

实验二 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 #include #include int main(void) { pid_t pid; printf(\ creation study\\n\ pid=fork( ); switch(pid) { case 0 : printf(\ break; case -1: printf(\ break; default: printf(\ break; } exit(0); }

【问题】:

1) 解释stdio.h、unistd.h、sys/types.h头文件的作用? 2) getpid()、getppid()、fork()的功能是什么? 3) 写出forkgrandchild.c的源代码。

(1)a.stdio.h头文件的作用是:就是指“standard input&output\ 就是说标准输入输出头文件。所以,用到标准输入输出函数时,就要 调用这个头文件! 原程序为:; b.nuistd.h头文件的作用是:是linux/unix的系统调用,包含了许多 unix系统服务的函数原型,例如 read(),write()和getpid()函数; c.sys/types.h头文件的作用是:在应用程序源文件中包含 以访问 _LP64 和 _ILP32 的定义。此头文件还包含适当时应使用的多个基本派生类型,尤其是以下类型更为重要: clock_t 表示系统时间(以时钟周期为单位)。 dev_t 用于设备号; off_t 用于文件大小和偏移量; ptrdiff_t 是一种带符号整型,用于对两个指针执行减法运算后所得的结果; size_t 反映内存中对象的大小(以字节为单位); ssize_t 供返回字节计数或错误提示的函数使用; time_t 以秒为单位计时; 所有这些类型在 ILP32 编译环境中保持为 32 位值,并会在 LP64 编译环境中增长为 64 位值。 (2)getpaid()的功能是:返回调用进程的标识符; getppid()的功能是:返回父进程标识; Fork()的功能是:创建一个与当前进程完全相同的拷贝。 (3)forkgrandchild.c的源代码: #include #include #include int main (void) { pid_t,pid1,pid2; printf(\pid1=fork(); switch(pid1) {

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 #include #include int globvar=5; int main(void) { pid_t pid; int var=1 , i; printf(\ vfork\\n\ /* pid=fork();*/ pid=vfork(); switch(pid) { case 0: i=3; while(i-->0) { printf(\ globvar++; var++; sleep(15); } printf(\ break; case -1: printf(\ exit(0); default : i=5; while(i-->0) { printf(\ globvar++; var++; sleep(5); } printf(\ exit(0); } }

【注意】:

将diffork.c中的sleep()的参数增大些,开启另一个终端,在该终端下输入ps aux查看父子进程的信息,特别是状态信息。 【结果】:

166e617rka7tdik0369x
领取福利

微信扫码领取福利

微信扫码分享