C 在linux上测试SIGINT和SIGHUP时出现有趣的类似小故障的行为
最近,我们一直在使用SIGINT和SIGHUP等信号进行测试,以及它们在Linux上正在进行的进程中的作用。运行以下代码返回了一些有趣的结果 如您所见,在无限循环中,它只是从0开始计数。然后,通过在它创建的进程上使用kill-SIGINT,我得到了以下结果:C 在linux上测试SIGINT和SIGHUP时出现有趣的类似小故障的行为,c,linux,C,Linux,最近,我们一直在使用SIGINT和SIGHUP等信号进行测试,以及它们在Linux上正在进行的进程中的作用。运行以下代码返回了一些有趣的结果 如您所见,在无限循环中,它只是从0开始计数。然后,通过在它创建的进程上使用kill-SIGINT,我得到了以下结果: 如您所见,在我请求例程打印的行之前,程序重复了最后一个数字,但并不总是这样。我真的很想知道原因。很可能是您无意中避免了可怕的错误 我认为发生的是,当printf正在将字符串格式化到输出缓冲区时,信号有时会中断。然后,信号处理程序中的put将
如您所见,在我请求例程打印的行之前,程序重复了最后一个数字,但并不总是这样。我真的很想知道原因。很可能是您无意中避免了可怕的错误 我认为发生的是,当printf正在将字符串格式化到输出缓冲区时,信号有时会中断。然后,信号处理程序中的put将更多字符串插入输出缓冲区。然后处理程序返回,printf插入换行符并刷新缓冲区 但是,猜猜如果这个信号刚好在刷新一个完整的8K输出缓冲区之前发生,会发生什么。缓冲区位置将位于末端。然后发生puts调用,没有意识到printf已经在刷新和清除缓冲区的过程中。它到底会把绳子放在哪里?一开始?最后?多余的数据printf是否正在写入puts添加的字符串?所有这些都是可能的
缓冲的C输出不可重入,不能在信号处理程序中使用。不能在信号处理程序中安全地使用stdio函数。请参阅man signal safety,了解您可以使用的设备。请阅读以下内容
#include <signal.h>
#include <stdio.h>
void routine(int p){
puts("Not finishing");
sleep(2);
}
main(){
int i = 0;
signal(SIGINT, routine);
signal(SIGHUP, routine);
while(1){
printf("%d \n", i++);
}
}