我正在弄清楚信号在 C 中是如何工作的。 这是旧考试中的一个例子:
#include<signal.h>
#include<unistd.h>
#include<stdio.h>
#include<errno.h>
//#include <sys/types.h>
void handler1(int sig) {
printf("Phantom");
exit(0);
}
int main()
{
pid_t pid1;
signal(SIGUSR1, handler1); //installing signal handler
if((pid1 = fork()) == 0) { //forking
printf("Ghost");
exit(0);
}
kill(pid1, SIGUSR1);
printf("Ninja");
return 0;
}
到目前为止,GCC 给了我两个答案 Ghost Ninja
和 Ninja Phantom
。它可以产生 Ghost Phantom Ninja
或任何其他由 3 个名字组成的组合吗?
我认为它可能产生 3 个名字的一种方式是:
Fork,在 Child 中运行,打印 Ghost
,在 Parent 中退出(0)=>,接受/处理信号并从信号处理程序打印 Phantom
,杀死 child,打印 忍者
。但我不确定我的“理论”是否站得住脚。
此外,kill(pid1, SIGUSR1)
会调用 handler()
吗?
谢谢!
最佳答案
让我们逐行检查一下。设置信号处理程序,然后 fork 。 child 打印“Ghost”并退出。 parent 让 child 打印“Phantom”并退出。然后父打印“忍者”。
所以你确实遇到了竞争条件。如果父级在子级打印“Ghost”之前触发了它的 SIGUSR1
,那么你会得到 Phantom Ninja
,或者可能是 Ninja Phantom
(不会杀死 block ?)
但是,如果您不能及时关闭信号,那么您将得到 Ghost Ninja
,因为子级在父级信号之前完成。我不认为反过来是可能的。
现在可以想象,信号可以准确地准时到达 printf
和 exit
之间,在这种情况下 Ghost
将结束,然后是 Phantom
,然后是 Ninja
- 或者反过来,我想。
它对操作系统时序非常挑剔和敏感。
@Everyone - 未经测试!随时反驳我,但我和 OP 一样有兴趣知道为什么。
关于c - C 中的信号处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4458920/