输入Ctrl + C时出现信号问题

时间:2013-01-18 13:14:28

标签: c linux signals

我是Linux编程的新手。我从一本书中复制了下面的代码:

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

void ouch (int sig)
{
    printf("OUCH! - I got signal %d\n", sig);
    (void) signal(SIGINT, SIG_DFL);
}

int main ()
{
    (void) signal(SIGINT, ouch);

    while(1)
    {
        printf("Hello World!\n");
        sleep(1);
    }

}

预计会在输入Ctrl+C时打印一些内容。但它只会打印Hello World!


修改 很抱歉,我已将Ctrl+C绑定为copy的快捷键。 对不起造成的麻烦。

3 个答案:

答案 0 :(得分:2)

我的建议是不要在siginal handler( ouch )中使用printf,它可能是未定义的行为。异步信号安全功能:The list of safe functions that can be call in signal handler man page

  

从信号处理程序中调用所有函数(如printf)是不安全的。      一种有用的技术是使用信号处理程序设置标志,然后检查该标志      如果需要,从主程序中打印一条消息。

参考:Beginning Linux Programming, 4th Edition,在本书中,您的代码将被解释,第11章:流程和信号,第484页

另一个有用的链接:
说明:Use reentrant functions for safer signal handling

答案 1 :(得分:1)

抱歉,我在这里看不到问题......但我可以猜出你感兴趣的内容。

printf()是一个有状态函数,因此不可重入。它使用FILE结构(变量名称为'stdin')来保持其状态。 (这就像调用fprintf(stdin,format,...))。

这意味着,依赖于实现和“运气”,从信号处理程序调用printf()可能会打印出您所期望的内容,但也可能无法打印或甚至可能崩溃或更糟,打破您的记忆!任何事情都可能发生。

因此,不要在信号处理程序中调用未明确标记为“信号安全”的函数。从长远来看,你会避免很多麻烦。

答案 2 :(得分:0)

fflush(stdout)放入信号处理程序中。它只是缓冲,然后第二个SIGINT退出程序,然后才能刷新缓冲区。