[linux]signal函数不起作用

本文探讨了一个使用gdb调试信号处理程序的问题。通过一个具体的代码示例,作者展示了如何在加入-g编译选项后,sig_int函数无法被调用的情况,并最终定位到问题原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include "apue.h"

#include <sys/wait.h>

static void sig_int(int); /* our signal-catching function */

int main(int argc, char *argv[])
{
    printf("uid = %d, gid = %d\n", getuid(), getgid());
    
    char buf[MAXLINE]; /* from apue.h */
    pid_t pid;
    int status;
    
    
    // register the signal handler
    if ( signal(SIGINT, sig_int) == SIG_ERR)
        err_sys("signal error");
    
    printf("%% "); /* print prompt (printf requires %% to print %) */
    while (fgets(buf, MAXLINE, stdin) != NULL) {
        if (buf[strlen(buf) - 1] == '\n')
            buf[strlen(buf) - 1] = 0; /* replace newline with null */
        if ((pid = fork()) < 0) {
            err_sys("fork error");
        } else if (pid == 0) { /* child */
            execlp(buf, buf, (char *)0);
            err_ret("couldn't execute: %s", buf);
            exit(127);
        }
        /* parent */
        if ((pid = waitpid(pid, &status, 0)) < 0)
            err_sys("waitpid error");
        printf("Last pid: %ld\n", (long)pid);
        printf("%% ");
    }
    
    exit(0);
}

void sig_int(int signo)
{
    printf("sig_int: interrupt\n%% ");
    exit(0); // I add this line to exit the program through CTRL+C (SIGINT), CTRL+D is to terminate the program
}

代码来自APUE Figure1.10

我编译之后用gdb调试,发现sig_int始终不会被调用

最后终于发现问题是因为编译选项加了-g,在调试状态下signal机制貌似被禁用了

### 回答1: Linux signal 函数是一个用于在进程之间传递信号的机制。它允许进程给其他进程发送特殊的消息,以通知其执行特定的操作。常用的信号有SIGINT(中断进程)、SIGKILL(强制终止进程)、SIGSTOP(暂停进程)等。使用 signal 函数可以自定义信号处理函数,在收到特定信号时执行指定操作。 ### 回答2: Linux signal 函数是一个系统调用,用于处理程序的信号。程序可以在运行中被其他进程或者操作系统发出的信号中断,而 signal 函数可以被用于捕获和处理这些信号。这些信号可以是,来自操作系统的信号,例如 SIGUSR1 和 SIGUSR2,以及在程序中使用 kill 发送的自定义信号。 signal 函数的语法如下: ```c #include <signal.h> void (*signal(int sig, void (*func)(int)))(int); ``` signal 函数的第一个参数为要处理的信号的编号,第二个参数为捕获到对应信号时要执行的处理函数。 其中,如果第二个参数的取值为 SIG_IGN,表示程序忽略该信号;如果取值为 SIG_DFL,则恢复为信号的默认行为。 signal 函数的返回值是一个函数指针,指向传入的第二个参数。 例如,以下代码可以用来为处理 SIGINT (中断信号) 注册一个信号处理函数: ```c #include <stdio.h> #include <stdlib.h> #include <signal.h> void sigint_handler(int sig) { printf("Caught sigint, exiting...\n"); exit(1); } int main() { signal(SIGINT, sigint_handler); while (1) { printf("Hello, world!\n"); sleep(1); } return 0; } ``` 在这个例子中,我们定义了一个名为 sigint_handler 的函数,当 SIGINT 信号被捕获时执行该函数。在主函数中,我们先调用 signal 函数来注册处理函数,然后开始了一个无限循环输出 "Hello, world!"。如果在运行中按下 Ctrl-C,将会捕获到 SIGINT 信号,此时就会调用 sigint_handler 函数,并输出相应的信息。 总体来说,signal 函数Linux 操作系统和应用程序中很常用的函数之一。通过使用 signal 函数,操作系统能够更好地管理进程,而应用程序也能更好的处理信号。 ### 回答3: Linux操作系统中的signal函数用于处理进程接收到信号时的行为。信号可以是来自操作系统内核或其他进程的中断,例如键盘输入,终端中断,内存错误等。 signal函数的语法为: `void (*signal(int sig, void (*func)(int)))(int);` 其中,sig表示将要处理的信号的种类,func表示接收到该信号时运行的处理程序。signal函数可以分为三种类型: 1. 信号的默认行为 操作系统提供一些默认的信号处理行为,例如SIGKILL和SIGSTOP表示强制终止和暂停程序,这些信号不能更改其默认行为。 2. 信号被忽略 如果将sig设置为SIG_IGN,则进程将忽略接收到的该信号。 3. 自定义信号处理程序 使用signal函数还可以定义自定义信号处理程序。这意味着当进程接收到该信号时,将调用指定的处理程序(func)。 不同的信号可以同时使用signal函数进行处理。但是,由于某些信号是操作系统保留的,因此可能无法更改其默认行为或忽略它们。 在Linux中,处理信号也可以使用其他函数,例如sigaction和sigprocmask。但signal函数因其简单的语法和易用性而广泛使用。 总之,signal函数Linux操作系统中一个非常有用的功能,可以为进程提供一个有效的方法来处理从操作系统中接收到的信息,并控制要采取的操作。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值