实验四   进程间通信实验

一、实验目的

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<stdio.h>

#include<signal.h>

#include<unistd.h>

#include<sys/types.h>

#include<sys/wait.h>

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 <stdio.h>

#include <sys/types.h>

#include <signal.h>

#include <unistd.h>

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<unistd.h>

# include<signal.h>

# include<stdio.h>

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<unistd.h>

# include<signal.h>

# include<stdio.h>

# include<stdlib.h>

#include<sys/wait.h>

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);

 }

}

  • 实验总结和体会(1分)

通过本次实验,让我了解到了什么是信号和什么是管道,也熟悉LINUX系统中进程之间软中断通信的基本原理和熟悉UNIX/LINUX支持的管道通信方式。然后通过实验也了解了信号是不能用于信息交换的,只能用于进程中断控制,以及通过键盘控制程序的中断。

 

 

 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐