操作系统 实验 - EP1
实验名称:进程管理
- 实验学时:2学时
预习报告 2021-04-28
实验原理摘要
- 系统调用是一种进入系统空间的办法,在OS的核心中都设置了一组用于实现各种系统功能的子程序,并将它们提供给程序员调用。程序员在需要OS提供某种服务的时候,便可以调用一条系统调用命令,去实现希望的功能,这就是系统调用。
- 在linux系统中,进程控制的功能是由内核的进程控制子系统实现的,并以系统调用的形式提供给用户进程或其他系统进程使用。
实验仪器
- PC机
- Linux (CentOS7)
实验内容及步骤
- 实验内容
- 编写一段程序,使用系统调用fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每个进程在屏幕上显示一个字符,父显示" parenter ",子进程分别显示“son”和“daughter”,观察记录显示结果,并分析原因
- 实验步骤
- 使用touch命令创建一个p.c文件
- 使用vi编辑p.c
- 编译文件
gcc p.c -o p
- 执行文件
./p
- 反复执行源文件,观察记录显示结果,并分析原因
实验报告 2021-04-29
实验目的及要求:
- 加深对进程概念的理解,明确进程和程序的区别与联系
- 进一步理解并发的概念,明确并发与顺序执行的异同
- 熟悉进程的创建、执行、阻塞、唤醒、终止等控制方法
实验环境
- PC机
- VMware Workstation Pro 15.x
- Linux (CentOS 7)
实验内容
- 编写一段程序,使用系统调用fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每个进程在屏幕上显示一个字符,父显示" parenter ",子进程分别显示“son ”和“daughter ”,观察记录显示结果,并分析原因。
实验步骤
- 打开终端在输入命令
touch p.c
- 在终端输入命令使用vi编辑
vi p.c
- 输入以下程序代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main(void){
int p1, p2;
while((p1 = fork()) == -1);
if(p1 == 0){
printf("Son ");
}else{
while((p2 = fork()) == -1);
if(p2 == 0){
printf("Daughter ");
}else{
printf("Parenter ");
}
}
printf("\n");
return 0;
} - 编译源文件
gcc p.c -o p
- 反复执行
./p
实验结果
-
观察反复执行后的输出结果, 我们可以发现程序运行结果有的是: “Parenter Son Daughter”, 有的是"Parenter Daughter Son", 结果有多种可能性。
-
自己本身的C语言程序是没有问题的,但是为什么会有多种输出结果?
- 对于父进程来说,除了创建两个子进程之外,还要输出"Parenter",于是父进程和子进程需要竞争CPU用来输出字符串"Parenter",但是CPU当前调用什么进程,就会执行什么进程。输出结果为"Parenter Son Daughter"的意思是:先运行父进程,并输出,然后子进程被创建,成为就绪队列,父进程可以运行,继续创建第二个子进程。就程序的并发性来看,是有多种输出结果的,父进程和子进程没有同步措施,因此父进程与子进程的输出内容会叠加在一起,所以父进程和子进程的输出结果是随机的。
- 对于子进程来说,因为在有三个进程时,不同的操作系统的调度算法不一样,因此也有其他的输出顺序。
- 对于Printf()函数来说,他在输出字符串的过程中不会被中断,因此,字符串内部字符顺序输出不变。但是由于进程并发运行的调度顺序和父子进程抢占CPU的问题,输出字符串的顺序和先后随着执行的不同而发生变化。
总结
- 通过这次上机实验,我们了解并掌握了如何在Linux操作系统下编辑、编译和运行C语言文件。
- 对于它的执行过程和整体的结构有一定的了解