Printf 在 C 信号处理程序中不起作用

问题描述 投票:0回答:3

首先有问题的代码(最小化案例):

#include <stdio.h>
#include <signal.h>

int counter = 0;

void react_to_signal(int n) {
    fprintf(stderr, "Caught!\n");
    counter++;
}

int main(int argc, char** argv) {

    signal(SIGINFO, react_to_signal);

    while (1) {
        printf("%d\n", counter);
    }

    return 0;
}

我运行代码,它按预期循环,打印出 0。然后在另一个 shell 中..

kill -s SIGINFO <pid_of_my_process>

信号已传递,

c
递增..但
fprintf
不会发生。

为什么会这样?处理程序代码在什么环境/上下文中运行?我可以在哪里阅读此内容?

c signals
3个回答
19
投票

简而言之:您不能安全地在信号处理程序中使用

printf

信号处理程序的手册页中有一个授权函数列表。里面没有

fprintf

那是因为这个函数不是可重入,主要是因为它可以使用

malloc
free
。 请参阅这篇文章了解详细说明。


2
投票

您可能需要 fflush stderr 才能在程序退出之前获取要写入的消息。


0
投票

除了重入问题之外,由于

counter
不是易失性的,它的读取可能会被提升到
while(1)
循环之外,导致循环中的 printf 始终打印 0,即使信号处理程序递增全局变量也是如此。

© www.soinside.com 2019 - 2024. All rights reserved.