实验5 进程管理
一、实验目的:
1. 了解进程与程序的区别,加深对进程概念的理解加;
2. 掌握进程并发执行的原理,及其所引起的同步、互斥问题的方法
二、实验要求:
完成实验内容并写出实验报告,报告应具有以下内容:
1. 实验目的。
2. 实验内容。
3. 程序流程图、程序执行情况、及运行结果分析。
4. 实验过程中出现的问题及解决方法。
5. 实验体会。
三、实验内容:
1.进程的创建。
编写一段程序,使用系统调用fork()创建两个子进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。试观察记录屏幕上的显示结果,并分析原因。
2.进程的控制。
修改在进程创建中已编写的程序,将每个进程输出一个字符改成每个进程输出一句话(长一些),观察程序执行时屏幕上出现的现象,并分析原因。
如果在程序中使用系统调用lockf()来给每个进程加锁,可以实现进程的互斥,观察并分析出现的现象。
3.实现进程的软中断通信
编制一段程序,使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按ctrl+c键);当捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号,子进程捕捉到信号后分别输出下列信息后终止:
Child Process1 is killed by Parent!
Child Process2 is killed by Parent!
父进程等待两个子进程终止后,输出如下的信息后终止:
Parent Process is killed!
多运行几次编写的程序,分析出现不同结果的原因。
思考问题:
该程序前面部分用了两个wait(0),为什么?
子进程中,Signal(17, stop);中的中断号17能否改变?如果能改变,还要做哪些相应修改?
如果把父进程中的任意一个kill语句注释掉,会出现什么结果?为什么?
四、实验指导:
1、相关函数
①fork函数:(课本P10-106,创建一个子进程的例子)
用于创建一个新的进程(子进程),格式如下:
Int fork();
正确返回:等于0,创建子进程,从子进程返回的ID值。
大于0,在父进程返回的子进程的进程ID值。
错误返回:等于-1,创建失败。
② lockf()函数
Lockf(1,1,0): 锁定
Lockf(1,0,0): 解除锁定
③signal()
signal()用来接收并设置对信号的处理方法。其调用格式如下:
#include<signal.h>
int signum;
signal(signum,function);
signum 的常用取值如下:
信号 |
功能 |
值 |
SIGINT |
键盘中断,按del键或break键 |
2 |
SIGKILL |
要求终止进程 |
9 |
SIGQUIT |
键盘按quit键 |
3 |
SIGCHLD |
子进程死 |
17 |
④wait()
用来控制父进程和子进程的同步。
在父进程中调用该函数,则父进程被阻塞,进入等待队列,等待子进程结束。当子进程结束时,产生一个终止状态字,系统向父进程发出SIGCHLD信号。当接收到该信号时,父进程提取子进程的终止状态字,从wait()函数返回继续执行原来的程序。
⑤kill()
用于删除执行中的程序或任务
Kill(int pid, int iid)
Pid:要被杀死的进程号,iid:向将要被杀死的进程发送的中断号。
⑥.Exit()
进程结束时调用的函数。在正常终止时,exit()函数返回进程结束状态。
⑦实现进程的软中断通信
<程序>
#include<stdio.h>
#include<signal.h>
#include<unistd.h>
Void waiting(),stop();
Int wait_mark;
Main()
{
int p1,p2;
while((p1= fork()) = = -1);
if (p1>0)
{
while((p2= fork()) = = -1);
if (p2>0)
{
Wait_mark=1;
Signal(SIGINT, stop); //如果键盘不认del键,思考此处如何解决?能否跳
Waiting(); // 过,使用别的方法?比如任意输入字符getchar():w继续
Kill(p1,16);
Kill(p2,17);
Wait(0);
Wait(0);
Printf(“/n parent process is killed!/n”);
Exit(0);
}
Else
{
Wait_mark=1;
Signal(17, stop);
Waiting();
Printf(“/n child process2 is killed by parent!/n”);
Exit(0);
}
}
Else
{
Wait_mark=1;
Signal(16, stop);
Waiting();
Printf(“/n child process1 is killed by parent!/n”);
Exit(0);
}
}
Void waiting()
{
While(wait_mark!=0);
}
Void stop()
{
Wait_mark=0;
}