一、实验目的
1、了解什么是信号。
2、熟悉LINUX系统中进程之间软中断通信的基本原理。
3、理解进程的同步关系。
4、了解什么是管道。
5、熟悉UNIX/LINUX支持的管道通信方式。
二、实验内容
1、编写一段程序,使用系统调用fork( )创建两个子进程,再用系统调用signal( )让父进 程捕捉键盘上来的中断信号(即按ctrl+c键),当捕捉到中断信号后,父进程用系统调用kill( )向两个子进程发出信号,子进程捕捉到信号后,分别输出下列信息后终止:
Child process 1 is killed by parent!
Child process 2 is killed by parent!
父进程等待两个子进程终止后,输出以下信息后终止:
Parent process is killed!
<参考程序>
#include
#include
#include
#include
#include
int wait_mark;
void waiting(),stop();
void main()
{int p1, p2;
signal(SIGINT,stop);
while((p1=fork())==-1);
if(p1>0) /*在父进程中*/
{
while((p2=fork())==-1);
If(p2>0) /*在父进程中*/
{ wait_mark=1;
waiting(0);
kill(p1,10);
kill(p2,12);
wait( );
wait( );
printf("parent process is killed!\n");
exit(0);
}
else /*在子进程2中*/
{
wait_mark=1;
signal(12,stop);
waiting();
lockf(1,1,0);
printf("child process 2 is killed by parent!\n");
lockf(1,0,0);
exit(0);
}
} else /*在子进程1中*/
{ wait_mark=1;
signal(10,stop);
waiting();
lockf(1,1,0);
printf("child process 1 is killed by parent!\n");
lockf(1,0,0);
exit(0);
}
}
void waiting()
{
while(wait_mark!=0);
}
void stop()
{
wait_mark=0;
}
实验要求:
⑴运行程序并分析结果。(2分)
答:按下ctrl+c中断进程时,程序才执行,父进程打印消息,父进程kill子进程,子进程1收到消息上锁,然后解锁关闭进程,随后子进程2同样操作,然后父进程打印,最后中断进程。
⑵该程序段前面部分用了两个wait(0),为什么?(1分)
答:wait(0暂时停止目前进程的执行,直到信号来到或子进程结束,如果在调用wait(0)时子进程已经结束,则wait(0)会立即返回子进程结束状态值。
⑶该程序段中每个进程退出时都用了语句exit(0),为什么?(1分)
答:因为在强调处强行退出程序,运行一次程序就结束。
2、司机售票员问题
编程用fork()创建一个子进程代表售票员,司机在父进程中,再用系统调用signal()让父进程(司机)捕捉来自子进程(售票员)发出的中断信号,让子进程(售票员)捕捉来自(司机)发出的中断信号,以实现进程间的同步运行。(2分)
#include
#include
#include
#include
int wait_mark;
int pid2;
void waiting(), stop ing();
void main() {
int pid1;
while ((pid1 = fork()) == -1);
if (pid1 > 0) { //司机进程
signal(SIGUSR2, stoping);
while (1) {wait_mark = 1;
sleep(1);
printf("drive\n");
printf("stop\n");
kill(pid1,SIGUSR1); //发送信号给售票员进程;
waiting(); //等待来自售票员的信号
printf("start\n");
printf("\n");
} } else { //售票员进程
signal(SIGUSR1, stoping);
while (1) { wait_mark=1;
waiting(); //等待来自司机的信号
printf("open\n");
printf("sale\n");
printf("close\n");
pid2 = getppid(); //得到司机进程识别码
kill(pid2,SIGUSR2); //发送信号给司机进程
}
}
}
void waiting() {
while (wait_mark != 0);
}
void stoping() {
wait_mark = 0;
}
3、编制一段程序,实现进程的管道通信。使用pipe()建立一条管道线。两个子进程p1和p2分别向管道各写一句话:
Child 1 is sending message!
Child 2 is sending message!
而父进程则从管道中读出来自于两个子进程的信息,显示在屏幕上。
<参考程序>
# include
# include
# include
int pid1,pid2;
main()
{ int fd[2];
char OutPipe[100],InPipe[100];
pipe(fd);
while((pid1=fork())= = -1);
if(pid1= =0)
{ lockf(fd[1],1,0);
sprintf(OutPipe,” child 1 process is sending message!”);
write(fd[1],OutPipe,50);
sleep(5);
lockf(fd[1],0,0);
exit(0);
}else
{while((pid2=fork())= = -1);
if(pid2= =0)
{ lockf(fd[1],1,0);
sprintf(OutPipe,” child 2 process is sending message!”);
write(fd[1],OutPipe,50);
sleep(5);
lockf(fd[1],0,0);
exit(0);
}else
{wait(0);
read(fd[0],InPipe,50);
printf(“%s\n”,InPipe);
wait(0);
read(fd[0],InPipe,50);
printf(“%s\n”,InPipe);
exit(0);
}
}
}
实验要求:运行程序并分析结果。(1分)
答:先 使用系统调用 fork( ) 创建两个子进程,再用系统调用 signal( ) 让父进程捕捉键盘上来的中断信号 ( 即按 ctrl+c 键 ) ,当捕捉到中断信号后,父进程用系统调用 kill( ) 向两个子进程发出信号,子进程捕捉到父进程发来的信号后,分别输出下列信息后终止 。
4.在父进程中用pipe()建立一条管道线,往管道里写一句话,两个子进程接收这句话。(2分)
# include
# include
# include
# include
#include
int pid1,pid2;
int main()
{ int fd[2];
char OutPipe[100],InPipe[100];
pipe(fd);
lockf(fd[1],1,0);
printf("parents is sending message!\n");
sprintf(OutPipe,"this is pepo parents msg!\n");
write(fd[1],OutPipe,50);
lockf(fd[1],0,0);
while((pid1=fork())== -1||(pid2=fork())== -1);
if(pid1==0&&pid2==0)
{ lockf(fd[0],1,0);
read(fd[0],InPipe,50);
printf("child 1 process is sending message!\n");
printf("child 2 process is sending message!\n");
printf("the message is %s\n",InPipe);
sleep(3);
read(fd[0],InPipe,50);
printf("the message is %s\n",InPipe);
lockf(fd[0],0,0);
exit(0);
}
}
通过本次实验,让我了解到了什么是信号和什么是管道,也熟悉LINUX系统中进程之间软中断通信的基本原理和熟悉UNIX/LINUX支持的管道通信方式。然后通过实验也了解了信号是不能用于信息交换的,只能用于进程中断控制,以及通过键盘控制程序的中断。