实验二:进程的控制
1 .实验目的
通过进程的创建、撤消和运行加深对进程概念和进程并发执行的理解,明确进程与程序之间的区别。
【答:进程概念和程序概念最大的不同之处在于:
(1)进程是动态的,而程序是静态的。
(2)进程有一定的生命期,而程序是指令的集合,本身无“运动”的含义。没有建立进程的程序不能作为1个独立单位得到操作系统的认可。
(3)1个程序可以对应多个进程,但1个进程只能对应1个程序。进程和程序的关系犹如演出和剧本的关系。
(4)进程和程序的组成不同。从静态角度看,进程由程序、数据和进程控制块(PCB)三部分组成。而程序是一组有序的指令集合。】
2 .实验内容
(1) 了解系统调用fork()、execvp()和wait()的功能和实现过程。
(2) 编写一段程序,使用系统调用fork()来创建两个子进程,并由父进程重复显示字符串“parent:”和自己的标识数,而子进程则重复显示字符串“child:”和自己的标识数。
(3) 编写一段程序,使用系统调用fork()来创建一个子进程。子进程通过系统调用execvp()更换自己的执行代码,新的代码显示“new program.”。而父进程则调用wait()等待子进程结束,并在子进程结束后显示子进程的标识符,然后正常结束。
3 .实验步骤
(1)gedit创建进程1.c
(2)使用gcc 1.c -o 1编译并./1运行程序1.c
#include<stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
void mian(){
int id;
if(fork()==0)
{printf(“child id is %d\n”,getpid());
}
else if(fork()==0)
{printf(“child2 id %d\n”,getpid());
}
else
{id=wait();
printf(“parent id is %d\n”,getpid());
}
}
(3)运行并查看结果
child’s pid=2894
child’s pid=2994
parent’s pid=2849
child’s pid=2897
child’s pid=2897
parent’s pid=2849
child’s pid=2894
child’s pid=2994
parent’s pid=2849
(4)gedit创建进程2.c
使用gcc 2.c -o 2编译并./2运行程序2.c#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);
}
}
(5)
(6)运行并查看结果
new program !
-rw-r–r--. 1 root root 2456 Apr 14 2019 /etc/passwd
child peocess PID:29035
4 .思考
(1) 系统调用fork()是如何创建进程的?
【答:(1)申请空白PCB
(2)为新进程分配资源
(3)初始化进程控制块
(初始化标识信息,初始化处理机状态信息,初始化处理机控制信息,)
(4)将新进程插入就绪队列】
(2)当首次将CPU 调度给子进程时,其入口在哪里?
【答:进程的进程控制块(PCB)结构中有指向其TTS(任务状态段)的指针, TTS里面存放着进程的入口。】
(3)系统调用execvp()是如何更换进程的可执行代码的?
【答:一个库函数通过调用execve来调用内核服务来执行指明的程序】
(4) 对一个应用,如果用多个进程的并发执行来实现,与单个进程来实现有什么不同?
【答:相对于单个进程而言,程序并发执行就是系统中的各个部分不再以单纯串行方式工作,在同一时刻系统中不是只有一个活动,而是存在许多并行活动。并且充分利用多核CPU的计算能力,方便进行业务拆分,提升应用性能。其次,时间片是CPU分配给各个线程的时间,因为时间非常短,所以CPU不断通过切换线程,让我们觉得线程是同时执行的,时间片一般是几十毫秒.而每次切换时,需要将当前的状态保存起来,以便能够进行恢复先前的状态,而这个切换是非常消耗性能的,过于频繁的切换反而无法发挥出多线程编程的优势.最后,因为单进程不会和其它进程争用竟源,也不会和其它进程有什么执行顺序不合理导理死锁,多进程并不仅发失去其封闭性并且会导致死锁现象】