LINUX-高級編成之信號作業,父子進程之間通信以及回收多個子進程

  1. 編寫一個程序,實現:父進程創建兩個子進程,然後父進程通過signal()來捕捉鍵盤發出的CTRL+C鍵,當按下CTRL+C鍵後,父進程分別向兩個子進程發出SIGUSR1和
    SIGUSR2,兩個子進程收到信號後分別打印
    “ child1 is killed by parent ! ” “ child2 is killed by parent ! ”,
    父進程等待兩個子進程都退出後,輸出“parent is finished”退出
//
//注意:一次wait或waitpid調用只能清理一個子進程,清理多個子進程應使用循環。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
pid_t pid1,pid2;
//信號處理回調函數
void signal_handler(int signo)//signo爲觸發的信號,爲signal()的第一個參數
{
	if(signo == SIGINT){
		printf("pid1=%d\n",pid1);

		kill(pid1,SIGUSR1);
		kill(pid2,SIGUSR2);
		
	}
	else if(signo == SIGUSR1 ){
		printf("child1 is kill by parent1\n");
		exit(0);

	}
	else if(signo == SIGUSR2){
		printf("child2 is kill by parent1\n");
		exit(0);

	}
}


int main(int argc, char const *argv[])
{

	pid1 = fork();
	pid2 = fork();
	int n = 2,wpid;

	if(pid1 == 0){

	
			// printf("%d\n",getpid() );
	         signal(SIGUSR1,signal_handler);
	         //不能夠讓子進程因爲觸發Ctrl+c的信號終止否則沒有進行接收到信號指令
	         signal(SIGINT,SIG_IGN);
			 pause();//捕捉信號

			 //考慮執行程序以後直接從pause 退出呢?還是先執行函數在推行湖呢
			 exit(1);
	}
	else if(pid1<0){
		perror("fork");
		exit(-1);

	}
    
	if(pid2 == 0){

			 signal(SIGUSR2,signal_handler);
			 signal(SIGINT,SIG_IGN);
			 pause();//捕捉信號

			 //考慮執行程序以後直接從pause 退出呢?還是先執行函數在推行湖呢
			 exit(1);
	}
	else if(pid2<0){
		perror("fork");
		exit(-1);

	}

	//首先要捕捉信號Ctrl+z
	struct sigaction act , oact;

	//指定信號處理回調函數
	act.sa_handler = signal_handler;
	//阻塞爲空
	sigemptyset(&act.sa_mask);
	//指定調用 signal_handler
	act.sa_flags = SA_SIGINFO;//0?

	//註冊信號
	sigaction(SIGINT, &act, &oact);

	
	pause();//捕捉信號

	//等待退出回收資源

            sleep(1);
            printf("i am parent. pid = %d\n",getpid());
            while(n>0)
            {
                    wpid=waitpid(-1,NULL,WNOHANG);
                    /*waitpid函數當第三個參數爲WNOHONG時,如果子進程未結束則返回0,
                    子進程結束調用成功返回子進程的pid.*/
                    if(wpid>0)//waipid調用成功
                       n--;
            }
            printf("wait finish.\n");
 
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章