[linux实验] signal与kill、signal一次性

signal与kill题目要求
编写程序,使用系统调用 fork()创建两个子进程,再用系统调用 signal()让父进程
捕捉键盘上发出的中断信号(即按 ctrl+c 或是 ctrl+\键),5 秒钟内若父进程未接收到 这两个软中断的某一个,则父进程用系统调用 kill()向两个子进程分别发送软中断信号
SIGUSR1 和 SIGUSR2,子进程获得对应的软中断信号,然后分别输出下列信息后终止:
Child process (pid=?) be killed!
Child process (pid=?) be killed!
父进程调用 wait()函数等待两个子进程终止后,输出以下信息,结束进程执行:
Parent process (pid=?) finished!

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void ParentStop(){
    return;
}
void ChildStop(){
    printf("Child process (pid=%d) be killed\n", getpid());
    exit();
}
int main(){
    pid_t p1, p2;
    p1=fork();
    if (p1){
        //parent
        p2=fork();
        if (p2){
            //parent
            signal(SIGINT, ParentStop);
            signal(SIGQUIT, ParentStop);
            sleep(5);
            kill(p1, SIGUSR1);
            kill(p2, SIGUSR2);
            wait(NULL);
            wait(NULL);
            printf("Parent process (pid=%d) finish\n", getpid());
        }else{
            //child2
            signal(SIGUSR2, ChildStop);
            sleep(6);
        }
    }else{
        //child1
        signal(SIGUSR1, ChildStop);
        sleep(6);
    }
    return 0;
}

父进程中用signal函数把SIGQUIT和SIGINT信号所指向的函数改成了自己编写的ParentStop函数,中间什么也不做直接返回。所以收到ctrl+\和ctfl+c的时候不会被结束而是调用了函数之后继续执行下面的语句。
利用kill函数在父进程中向两个子进程发送sigusr1信号和sigusr2信号,而两个子进程接收这两个信号的动作都是输出一条语句之后exit。
所以这个程序的运行结果就是:
当执行中不给程序ctrl+\和ctfl+c信号的时候,父进程会给子进程发送信号。
在这里插入图片描述
当执行过程中给了ctrl+\和ctfl+c信号之后。由于两个子进程是从父进程中继承来的,父进程是从shell进程继承来的,他们都有对stdin和stdout的读写权限。所以都会接收到结束信号。这时父进程由于改变了执行动作,所以父进程执行结果不变,而两个子进程不会再输出语句了。
在这里插入图片描述


注意signal的声明具有一次性,即它声明后,当进程收到指定信号会跳转到指定函数去执行, 并且会把这个信号的指定效果恢复成默认值。当这个进程再次接受到这个信号后,就不会在去执行我们指定的函数了。
如果有需要的话需要在接受信号之前再次调用signal函数来声明。


猜你喜欢

转载自blog.csdn.net/weixin_42172261/article/details/106237028