“小忙”解释一下,三天没更博 是因为有事情在忙,据Keep APP不完整计程 + 不完整计时,三天骑行一百多公里,第一次觉得骑车真的太累了……
不过我又回来啦 今日份继续更博咯,开启正文叭!
Part2. 进程控制
往期回顾:
Part0. 实验环境
Part1-1.熟悉UKylin环境
Part1-2.熟悉UKylin环境
一、实验目的
- 掌握进程的概念,进一步理解进程和程序的区别。
- 认识和了解并发执行的实质。
- 掌握fork()、wait()、exit()函数。
二、实验内容
- 运行下面程序,查看程序运行结果,了解并掌握fork()函数调用的结果。
#include<stdio.h>
#include<unistd.h>
int main()
{
int pid;
pid = fork();
if(pid < 0)
printf("返回值为:pid = %d. Failed to create process. \n",pid);
else if(pid == 0)
printf("返回值为:pid = %d. I'm the child process. My Process ID is:%d. \n", pid, getpid());
else
{
wait(0);
printf("返回值为:pid = %d. I'm the parent process. My Process ID is:%d. \n", pid, getpid());
}
return 0;
}
运行结果:
分析:fork()函数创建一个子进程,该子进程复制父进程的PCB。当返回值为0时代表子进程,当返回值是大于0是代表父进程,返回值为负数时表示创建进程失败。上述代码创建进程的父进程的进程号为5252,子进程的进程号为5253。
fork( )
功能:创建一个新的子进程。其子进程会复制父进程的数据与堆栈空间,并继承父进程的用户代码、组代码、环境变量、已打开的文件代码、工作目录和资源限制。
系统调用格式:
int fork()
如果fork调用成功则在父进程会返回新建立的子进程标识符(PID),而在新建立的子进程中则返回0。如果fork失败则直接返回-1。
修改后代码:
#include<stdio.h>
#include<unistd.h> //fork() getpid()
#include<stdlib.h> //exit()
#include<sys/wait.h> //wait()
int main()
{
int pid;
pid = fork();
if(pid < 0)
printf("返回值为:pid = %d. Failed to create process. \n",pid);
else if(pid == 0)
{
printf("返回值为:pid = %d. I'm the child process. My Process ID is:%d. \n", pid, getpid());
exit(0);
}
else
{
wait(0);
printf("返回值为:pid = %d. I'm the parent process. My Process ID is:%d. \n", pid, getpid());
}
return 0;
}
分析:调用了wait函数和exit函数,父进程等待子进程执行完再执行。
1、wait()
等待子进程运行结束。如果子进程没有完成,父进程一直等待。wait( )将调用进程挂起,直至其子进程因暂停或终止而发来软中断信号为止。如果在wait( )前已有子进程暂停或终止,则调用进程做适当处理后便返回。
2、exit()
终止进程的执行。通常父进程在创建子进程时,应在进程的末尾安排一条exit( )语句,使子进程自我终止。exit(0)表示进程正常终止,exit(1)表示进程运行有错,异常终止。
如果调用进程在执行exit( )时,其父进程正在等待它的终止,则父进程可立即得到其返回的整数。操作系统须为exit( )完成以下操作:
(1)关闭软中断
(2)回收资源
(3)写记帐信息
(4)置进程为“僵死状态”
1.进程的创建
编写一段程序,使用系统调用fork( )创建两个子进程,在系统中有一个父进程和两个子进程活动。让每个进程在屏幕上显示一个字符;父进程显示字符“f”,两个子进程分别显示字符“s” 和“d”。多次运行可执行程序,观察记录屏幕上的显示结果,并分析原因。画出进程树的结构图。
#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<sys/wait.h>
int main()
{
int p1,p2;
while((p1 = fork()) == -1); // 创建成功为止
if(p1 == 0) //如果是子进程
{