计算机操作系统实验二之进程的控制

1 .实验目的
通过进程的创建、撤消和运行加深对进程概念和进程并发执行的理解,明确进程与程序之间的区别。
答:进程和实验的区别:程序是由 多个进程 运行的程序是给用户操作 进程是给程序支持的进程是动态的,而程序是静态的。进程有一定的生命期,而程序是指令的集合,本身无“运动”的含义。没有建立进程的程序不能作为1个独立单位得到操作系统的认可。1个程序可以对应多个进程,但1个进程只能对应1个程序。进程和程序的关系犹如演出和剧本的关系。
2 .实验内容
(1)了解系统调用fork()、execvp()和wait()的功能和实现过程。
答:1.系统调用fork允许一个进程(父进程)创建新进程(子进程) 会从主程序中复制出一个新的程序,如果folk返回0就是子程序,否则那就是还是当前的程序。
2.系统调用wait 父进程用来获取子进程状态.在主程序中你可以自己决定要等待子程序返回才继续运算这样保持同步还是异步的不等子程序的结果就继续往下运行
3. execvp: 这个函数如果正常运行是不会有返回的,有返回说明启动的程序出现异常。对于没有返回的函数理解起来比较费劲,因为通常我们讲函数都会有返回的,但如果想到这个是一个独立的进程,那就可以理解了。
(2) 编写一段程序,使用系统调用fork()来创建两个子进程,并由父进程重复显示字符串“parent:”和自己的标识数,而子进程则重复显示字符串“child:”和自己的标识数。
#include<unistd.h>
#include<stdio.h>
void main()
{
int p1,p2;
while((p1=fork())-1);
if(p1
0)
printf(“child’s pid=%d\n”,getppid());
else
{
while((p2=fork())-1);
if(p2
0)
printf(“child’s pid=%d\n”,getppid());
else printf(“parent’s pid=%d\n”,getppid());
}}
计算机操作系统实验二之进程的控制

(2)编写一段程序,使用系统调用fork()来创建一个子进程。子进程通过系统调用execvp()更换自己的执行代码,新的代码显示“new program.”。而父进程则调用wait()等待子进程结束,并在子进程结束后显示子进程的标识符,然后正常结束。
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/wait.h>
int main()
{
pid_t pid;
char *a[]={“ls”,"-l","/etc/passwd",0};
int result;
pid=fork();
if(pid<0){
printf(“frok error!”);}
else if(pid==0){
printf(“new program !\n”);
execvp(“ls”,a);
exit(0);
}
else{
int e=waitpid(pid,&result,0);
printf(“child peocess PID:%d\n”,e);
exit(0);
}
}
计算机操作系统实验二之进程的控制
3 .思考
(1)系统调用fork()是如何创建进程的?
答:fork()函数返回两次返回值,对父进程而言,返回值为-1时,代表创建子进程失败,返回值非0值时,这个返回值时子进程的pid。对子进程而言,返回值为0。
(2)当首次将CPU 调度给子进程时,其入口在哪里?
答:进程的进程控制块(PCB)结构中有指向其TTS(任务状态段)的指针,TTS里面存放着进程的入口。系统为所有用户进程维护了一个task table,在这里面存放着指向每个进程的进程控制块(PCB)的指针。在某次时钟中断中,轮到一个进程被唤醒(新建进程也得乖乖进入任务队列排队),CPU读取该进程PCB结构中那个指向TTS的指针。各进程的TTS构成一个表,表的段描述符存放于GDT(全局段描述符表)或者LDT(局部段描述符表)。然后CPU读取TTS中的各项数据并且根据它的各项值来设置寄存器,包括CS(代码段选择子)和IP(指令偏移地址),而这就是进程的入口。接下来,CPU开始执行进程的指令。
(3)系统调用execvp()是如何更换进程的可执行代码的?
答: execvp: 这个函数如果正常运行是不会有返回的,有返回说明启动的程序出现异常。对于没有返回的函数理解起来比较费劲,因为通常我们讲函数都会有返回的,但如果想到这个是一个独立的进程,那就可以理解了。
(4)对一个应用,如果用多个进程的并发执行来实现,与单个进程来实现有什么不同?
答:1.多进程:优点:初期实现起来比较简单快捷省时,单一性使部署和运营比较简单,内存占用少。进程内部通信效率高
缺点:数据共享复杂占用内存多,切换复杂,CPU利用率低,创建销毁复杂且慢。
2.单进程:缺点:中后期随着业务逻辑的复杂变化和需求的增加会臃肿,任何模块的崩溃会导致整个进程的失败,单进程中多线程难以调试。
优点: 初期实现起来比较简单快速,省去了进程间通信的工作 单一性使得部署和运营比较简单 内存占有少, 现在内存都很便宜,这个优势不明显. 进程内部通信效率比IPC/socket等要高效。