题目:

编写一段程序,使用系统调用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>

void go();
void stop1(),stop2();

int p1,p2;

main( )
{	
	while((p1=fork( ) )==-1); /*创建子进程p1*/
	if (p1>0)
	{
	 while((p2=fork( ) )==-1); /*创建子进程p2*/
	  if(p2>0)
	 {	  
          printf("This is parent %d.\n", getpid()); 
	  signal(SIGINT,go); /*接收到信号,转go*/
          pause();

          sleep(2);               // wait for the operation of child

	  wait(0);
          wait(0);
	  printf("Parent process is killed!\n");
	  exit(0);
	 }
	  else if(p2 == 0)
	 {	
          printf("This is child_2 %d.\n", getpid()); 
	  signal(17,stop2); /*接收到软中断信号17,转stop2*/
          pause();
	 }
	}
	else if(p1 == 0)
	{	
         printf("This is child_1 %d.\n", getpid()); 
	 signal(16,stop1); /*接收到软中断信号16,转stop1*/
         pause();
	}
}

void go()
{
	kill(p1,16); 	/*向p1发软中断信号16*/
	kill(p2,17); 	/*向p2发软中断信号17*/
}

void stop2()
{
	printf("Child process 2 is killed by parent!\n");
	exit(0);
}

void stop1()
{
	printf("Child process 1 is killed by parent!\n");
	exit(0);
}

但是这段程序,并没有按照预期的结果,输出“Child process 1 is killed by parent”和"Child process 2 is killed by parent!"。

在输入Ctrl+C后,父进程和子进程同时结束了,子进程并没有处理为其设置的信号,是什么原因呢?

因为子进程从父进程中继承了Ctrl+C信号,及其默认的处理程序,在子进程中并没有屏蔽Ctrl+C信号,因此,当输入Ctrl+C信号时,子进程会在处理父进程为其指定的信号之前,调用默认的处理Ctrl+C信号的程序,直接退出。因此,解决这个问题的办法,就是在子进程中屏蔽掉系统默认的对Ctrl+C信号的处理,如下:

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <errno.h>

#include <unistd.h>
void go();
void stop1(),stop2();
pid_t p1,p2;
void main( )
{	
	int status = -1;
	int rtv;
	while((p1=fork( ) )==-1); /*创建子进程p1*/
	if (p1>0)
	{
	 while((p2=fork( ) )==-1); /*创建子进程p2*/
	  if(p2>0)
	 {	  
	  printf("Parent process %d\n", getpid());
	  signal(SIGINT,go); /*接收到信号,转go*/
      pause();
	  sleep(2);
	  wait(NULL);
      wait(NULL);
	  printf("Parent process is killed!\n");
	  exit(0);
	 }
	  else
	 {	 
		printf("Process 2, pid %d\n", getpid());
		signal(SIGINT, SIG_IGN);	//屏蔽默认的 SIGINT信号处理
		signal(SIGUSR2, stop2);
		if(signal(SIGUSR2,stop2) == SIG_ERR) {
			printf("Can't catch SIGUR2");
		}
		pause();
		printf("Process 2 End\n");
	 }
	}
	else
	{	
		printf("Process 1, pid %d\n", getpid());
		signal(SIGINT, SIG_IGN);	//屏蔽默认的 SIGINT信号处理
		if(signal(SIGUSR1,stop1) == SIG_ERR) {
			printf("Can't catch SIGUR2");
		}
        pause();
		printf("Process 1 End\n");
	}
	printf("child exit status is %d\n", WEXITSTATUS(status));
}

void go()
{
	int rtv;
	printf("Func go\n");
	rtv = kill(p1,SIGUSR1); 	/*向p1发软中断信号16*/
	if(rtv) {
		printf("fail to send signal 16 to p1\n");
	} else {
	
		printf("Succed in sending signal 16 to p1\n");
	}
	rtv = kill(p2,SIGUSR2); 	/*向p2发软中断信号17*/
	if(rtv) {
		printf("fail to send signal 17 to p2\n");
	} else {
		printf("Succed in sending signal 17 to p2\n");
	}
}
void stop2()
{
	printf("Child process 2 is killed by parent!\n");
	exit(0);
}
void stop1()
{
	printf("Child process 1 is killed by parent!\n");
	exit(0);
}

参考:UNIX环境高级编程_第二版中文

GitHub 加速计划 / li / linux-dash
10.39 K
1.2 K
下载
A beautiful web dashboard for Linux
最近提交(Master分支:2 个月前 )
186a802e added ecosystem file for PM2 4 年前
5def40a3 Add host customization support for the NodeJS version 4 年前
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐