操作系统B2上机实验进程解析.docx
- 文档编号:30510726
- 上传时间:2023-08-16
- 格式:DOCX
- 页数:14
- 大小:643.37KB
操作系统B2上机实验进程解析.docx
《操作系统B2上机实验进程解析.docx》由会员分享,可在线阅读,更多相关《操作系统B2上机实验进程解析.docx(14页珍藏版)》请在冰豆网上搜索。
操作系统B2上机实验进程解析
实验二Linux进程实验
姓名:
段叶叶班级:
信息1302学号:
07131052
地点:
东区实验室FF109
时间:
2014年10月13日星期一
成绩:
一、实验内容
1.创建进程的系统调用fork();
2.创建进程的系统调用vfork();
3.执行新程序的系统调用exec();
4.等待进程结束的系统调用wait()或waitpid()。
前三题必做,最后一题选做。
二、实验目的
熟悉进程的系统调用。
三、实验环境
登陆Linux虚拟机,进入Linuxshell,提示符为$,表示普通用户提示符。
四、实验题目
1.【题目】:
编写程序forkgrandchild.c,用来创建孙子进程。
【要求】:
在读懂程序forktest.c的基础上,编写程序
forkgrandchild.c(forkgrandchild.c创建在用户名(如wm)目录下的process目录下),所创建的程序forkgrandchild.c可实现创建孙子进程,并显示孙子进程的pid,其父进程的pid,forkgrandchild.c要求可读性好,用户界面友好。
【预备知识】:
1)Linux进程状态
●运行状态:
程序正在运行或在运行队列中等待运行。
●可中断等待状态:
进程正在等待某个事件完成,等待过程可被信号或定时器唤醒。
●不可中断等待状态:
进程正在等待某个事件完成,不可被信号或定时器唤醒,必须等待事件的发生,才可唤醒。
●僵死状态:
进程已终止,但进程描述符依然存在,直到父进程调动wait()函数后释放。
●停止状态:
进程因收到SIGSTOPSIGSTPSIGTINSIGTOU信号后停止运行或该进程正在被跟踪(调式程序时)。
2)ps命令
●ps命令可查看进程的当前状态。
●如psaux(相关命令参数自学)
●对ps命令结果字符的解释
<(高优先级进程)、N(低优先级进程)、L(内存锁页,即页不可被换出内存)、s(该进程为会话首进程)、l(多线程进程)、+(进程位于前台进程组)、R(运行状态)、Z(僵死状态)、D(不可中断等待状态)、S(可中断等待状态)、T(停止状态)。
3)fork()函数
fork()是创建一个新进程的唯一方法,子进程可以继承其父进程几乎所有的资源。
在命令行下使用man2fork可获得该函数的函数声明。
fork()有两个返回值。
成功调用fork后,当前进程实际上已经分裂为两个进程,一个是原来的父进程,另一个是刚刚创建的子进程。
父子进程在调用fork地方分开,一个是父进程调用fork的返回值,返回值为刚刚创建的子进程的pid;另一个是子进程中fork函数的返回值,为0。
fork返回两次的前提是进程创建成功,若失败返回为-1。
用返回值可区分父子进程。
fork之后是父还是子进程先运行是不确定的,这取决于内核所使用的调度算法,一般是交替执行,使进程享有同等执行权。
forktest.c源代码
#include
#include
#include
intmain(void)
{
pid_tpid;
printf("processcreationstudy\n");
pid=fork();
switch(pid)
{
case0:
printf("childprocessisrunning,curpidis%d,parentpidis%d\n",pid,getppid());
break;
case-1:
printf("processcreationfailed\n");
break;
default:
printf("parentprocessisrunning,childpidis%d,parentpidis%d\n",pid,getpid());
break;
}
exit(0);
}
【问题】:
1)解释stdio.h、unistd.h、sys/types.h头文件的作用?
2)getpid()、getppid()、fork()的功能是什么?
3)写出forkgrandchild.c的源代码。
(1)a.stdio.h头文件的作用是:
就是指“standardinput&output"意思就是说标准输入输出头文件。
所以,用到标准输入输出函数时,就要调用这个头文件!
原程序为:
b.nuistd.h头文件的作用是:
是linux/unix的系统调用,包含了许多unix系统服务的函数原型,例如read(),write()和getpid()函数;
c.sys/types.h头文件的作用是:
在应用程序源文件中包含
此头文件还包含适当时应使用的多个基本派生类型,尤其是以下类型更为重要:
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("processcreationstudy.\n");
pid1=fork();
switch(pid1)
{
case0:
printf("childprocessisrunning,
curpidis%d,parentpidis%d\n",pid,getppid());
pid2=fork(pid1);
switch(pid2)
{
case0:
printf("grandchildprocessisrunning,curpidis%d,
parentpid is %d\n",pid,getppid());
break;
case-1:
printf("process creation failed\n");
break;
default:
printf("parent process is running ,grandchildpid is %d,parentpid is %d\n",pid ,getpid());
break;
}
case-1:
printf("process creation failed\n");
break;
default:
printf("parent process is running ,childpid is %d,parentpid is %d\n",pid ,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
intglobvar=5;
intmain(void)
{
pid_tpid;
intvar=1,i;
printf("forkisdiffirentwithvfork\n");
/*pid=fork();*/
pid=vfork();
switch(pid)
{
case0:
i=3;
while(i-->0)
{
printf("childprocessisrunning\n");
globvar++;
var++;
sleep(15);
}
printf("childisglobvar=%d,var=%d\n",globvar,var);
break;
case-1:
printf("parentcreationfailed\n");
exit(0);
default:
i=5;
while(i-->0)
{
printf("parentprocessisrunning\n");
globvar++;
var++;
sleep(5);
}
printf("parentisglobvar=%d,var=%d\n",globvar,var);
exit(0);
}
}
【注意】:
将diffork.c中的sleep()的参数增大些,开启另一个终端,在该终端下输入psaux查看父子进程的信息,特别是状态信息。
【结果】:
3.【题目】:
执行新程序的系统调用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
intmain(intargc,char*argv[],char**environ)
{
inti;
printf("iamaprocessimage!
\n");
printf("mypid=%d,parentpid=%d\n",getpid(),getppid());
printf("uid=%d,gid=%d\n",getuid(),getgid());
for(i=0;i printf("argv[%d]: %s\n",i,argv[i]); } execve.c源代码 #include #include #include intmain(intargc,char*argv[],char**environ) { pid_tpid; intstat_val; printf("execexample! \n"); pid=fork(); switch(pid) { case-1: perror("processcreationfailed\n"); exit (1); case0: printf("childprocessisrunning\n"); printf("mypid=%d,parentpid=%d\n",getpid(),getppid()); printf("uid=%d,gid=%d\n",getuid(),getgid()); execve("processimage",argv,environ); printf("processnevergotohere! \n"); exit(0); default: printf("parentprocessisrunning\n"); break; } wait(&stat_val); exit(0); } 【注意】: 1)理解带参数的main()函数。 2)在Linux命令行下,使用manexecve获取该函数的帮助。 【问题】: 先编译链接processimage.c,再编译链接execve.c,查看运行结果,结果说明了什么? 运行结果截图见下页 4.【题目】: 等待进程结束的系统调用wait()或waitpid()。 【要求】: 上机实现下面wait.c的运行,体会等待进程结束wait()系统调用。 【预备知识】: 子进程先于父进程终止,而父进程又没有调用wait函数等待子进程结束,子进程进入僵死状态,并会一直保持下去除非重启。 子进程进入僵死状态时,内核只保存该进程的一些必要信息以备父进程所需。 此时子进程始终占用着资源,同时也减少了系统可创建的最大进程数。 如果子进程先于父进程终止,且父进程调用了wait或waitpid函数,则父进程会等待子进程结束,就不会使子进程变为僵尸进程。 wait.c源代码 #include #include #include #include intmain() { pid_tpid; char*msg; intk; intexit_code; printf("studyhowtogetexitcode\n"); pid=fork(); switch(pid) { case0: msg="childprocessisrunning"; k=5; exit_code=37; break; case-1: perror("processcreationfailed\n"); exit (1); default: exit_code=0; break; } if(pid! =0) { intstat_val; pid_tchild_pid; child_pid=wait(&stat_val); printf("childprocesshasexited,pid=%d\n",child_pid); if(WIFEXITED(stat_val)) printf("childexitedwithcode%d\n",WEXITSTATUS(stat_val)); else printf("childexitedabnormally\n"); } else { while(k-->0) {puts(msg); sleep (1); } } exit(exit_code); } 【注意】: 1)在Linux命令行下,使用man命令获取wait和waitpid函数的帮助。 2)父进程调用wait后被挂起等待(此时打开另一个终端,输入psaux命令可查看父进程的状态),直到子进程结束。 子进程正常结束后,wait函数返回刚刚结束运行的子进程的pid,宏WEXITSTATUS获取子进程的退出码。 【问题】: 编译链接wait.c,并运行wait,结果说明了什么?
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 B2 上机 实验 进程 解析