我是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
的快捷键。
对不起造成的麻烦。
答案 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退出程序,然后才能刷新缓冲区。