Linux- 调用signal 设定特定信号sig的处理函数handler

调用 signal 可以设定特定信号 sig 的处理函数 handler。进程收到另⼀个调用 kill 发送过来的信号 sig 时,便会开始执行 handler 函数。通过这⼀对函数便可以实现最基本的进程间通信,以下面的程序为例:

#include 
#include 
#include 
#include 
#include 

void sig_routine(int dunno) {
    switch (dunno)
    {
    case 6:
        printf("\tI am child process, I receive signal SIGABRT\n");
        break;
    }
}

int main() {
    pid_t pid;
    int status;
    int sig;
    signal(SIGABRT, sig_routine);

    if (!(pid = fork())) {
        printf("\tHi I am child process !\n");
        sleep(10);
        return 0;
    }
    else {
        sleep(1);
        kill(pid, SIGABRT); // // Sends a SIGABRT (abort program) signal
        wait(&status);

        if (WIFSIGNALED(status)) {
            printf("child process receive signal %d\n", WTERMSIG(status));
        }
        else {
            printf("child process exits normally with %d\n", WTERMSIG(status));
        }
    }
    return 0;
}

运行结果如下:

majn@tiger:~/C_Project/signal_project$ ./signal_demo 
        Hi I am child process !
        I am child process, I receive signal SIGABRT
child process exits normally with 0

这个程序展示了如何在父子进程之间使用信号。它创建一个子进程,父进程向子进程发送一个 SIGABRT 信号,子进程捕获并处理这个信号,然后继续执行并最终正常结束。

程序的关键部分如下:

  1. 信号处理函数 sig_routine(int dunno):

    • 当子进程接收到 SIGABRT 信号(其值为6)时,它调用此函数来处理该信号。
    • 此函数仅打印消息,表示子进程已接收到该信号,并继续执行。
  2. 主程序:

    • 通过 signal(SIGABRT, sig_routine);,程序为 SIGABRT 信号设置了一个处理函数,即 sig_routine
    • 使用 fork() 创建子进程。
    • 子进程打印一条消息表示它是子进程,然后休眠10秒,并正常退出。
    • 父进程休眠1秒,确保子进程已经开始执行并注册了信号处理函数。然后,它向子进程发送一个 SIGABRT 信号。
    • 父进程使用 wait(&status) 等待子进程结束,并获取子进程的结束状态。
    • 根据子进程的结束状态,父进程打印相应的消息。

输出结果如下:

  • 子进程首先输出 “Hi I am child process!”。
  • 当子进程接收到 SIGABRT 信号时,它输出 “I am child process, I receive signal SIGABRT”。
  • 最终,父进程输出 “child process exits normally with 0”,因为子进程正常结束,没有因为接收到信号而被终止。

所以,这个程序的关键是理解信号的默认行为(例如,SIGABRT 默认会终止进程)可以被覆盖,如果为该信号注册了一个处理函数。在这个例子中,处理函数只是简单地打印了一条消息,而不是终止进程。


如果不为该信号注册一个处理函数,则运行结果如下:

#include 
#include 
#include 
#include 
#include 

int main() {
    pid_t pid;
    int status;
    int sig;
    // signal(SIGABRT, sig_routine);

    if (!(pid = fork())) {
        printf("\tHi I am child process !\n");
        sleep(10);
        return 0;
    }
    else {
        sleep(1);
        kill(pid, SIGABRT); // // Sends a SIGABRT (abort program) signal
        wait(&status);

        if (WIFSIGNALED(status)) {
            printf("child process receive signal %d\n", WTERMSIG(status));
        }
        else {
            printf("child process exits normally with %d\n", WTERMSIG(status));
        }
    }
    return 0;
}

运行结果为:

majn@tiger:~/C_Project/signal_project$ ./signal_demo 
        Hi I am child process !
child process receive signal 6

你可能感兴趣的:(C,Linux,linux,C)