c - C 中的信号处理

标签 c signals

我正在弄清楚信号在 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 NinjaNinja 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,因为子级在父级信号之前完成。我不认为反过来是可能的。

现在可以想象,信号可以准确地准时到达 printfexit 之间,在这种情况下 Ghost 将结束,然后是 Phantom,然后是 Ninja - 或者反过来,我想。

它对操作系统时序非常挑剔和敏感。

@Everyone - 未经测试!随时反驳我,但我和 OP 一样有兴趣知道为什么。

关于c - C 中的信号处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4458920/

相关文章:

c - 将字符串读入 char * 时出现段错误

c - 使用链表进行循环调度

c - 检查备用信号堆栈(不同的分配方式)

c - 这段代码中指针运算的目的是什么?

c - 了解 wait() 和 signal()

c - 如何从 MATLAB 运行 C 可执行文件?

bash - cygwin ssh 在退出时给出 "Killed by signal 1"

c 替代 signal() + alarm()

c - C 标准库中的信号 <signal.h> 是操作系统中的信号吗?

windows - 我可以向 Windows 上的应用程序发送 ctrl-C (SIGINT) 吗?