输入Ctrl+时发出信号;C

输入Ctrl+时发出信号;C,c,linux,signals,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(SIGIN

我是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);
    }

}
#包括
#包括
#包括
虚空哎哟(内部信号)
{
printf(“哎哟!-我得到信号%d\n”,信号);
(无效)信号(SIGINT、SIG_DFL);
}
int main()
{
(无效)信号(信号,哎哟);
而(1)
{
printf(“你好,世界!\n”);
睡眠(1);
}
}
当输入
Ctrl+C
时,它应该打印一些东西。但是它除了打印
Hello World之外什么也不做


编辑: 很抱歉,我已将
Ctrl+C
绑定为
copy
的快捷键。
很抱歉造成麻烦。

我的建议是不要在信号处理程序(哎哟)中使用
printf
,这可能是未定义的行为。异步信号安全函数:

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

参考资料:,在这本书中,您的代码得到了准确的解释,第11章:过程和信号,第484页

另一个有用的链接:

说明:

在信号处理程序中放置一个
fflush(stdout)
。它刚刚被缓冲,然后第二个SIGINT在缓冲区被刷新之前退出了程序。

对不起,我看不到这里有问题。。。但我能猜出你对什么感兴趣

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

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


所以,不要从没有明确标记为“信号安全”的信号处理程序中调用函数。从长远来看,你将避免很多令人头痛的事情。

在这个问题和你的答案的上下文中,链接的“解释”将解释什么?它肯定不会…;-)。无论如何,这并不能回答我的问题。或者我遗漏了什么?本例中未定义的行为(linux)意味着您可能最终得到交错输出,仅此而已。这不能解释所报道的行为。你是从书上抄来的?什么样的书会抛出一个未使用的返回>\u。。。并教您从信号处理程序调用
printf()
。您可以粘贴完整的输出,包括用于生成和运行此代码的命令吗?@alk实际上,这本书已经警告说,不建议在处理程序中使用
printf
。我只想尝试一下。
write
是异步信号安全的,因此您可以使用
write(STDERR_FILENO,
ouch
中。这是未缓冲的,不会与
printf
使用的已缓冲的
文件*stdout
交互。
\n
是否应该刷新
stdout
的缓冲区?@alk如果它处于行缓冲模式,这通常是,但可能不取决于此函数的测试方式。Adding显式刷新应该使其明确无误。