gpt4 book ai didi

c - 信号 - SIGUSR1 类练习

转载 作者:行者123 更新时间:2023-12-03 09:57:01 27 4
gpt4 key购买 nike

我得到了这个作为类练习。我不得不分析输出而不运行它,我想
输出应该是 num=4。
但实际上这段代码运行后的输出是:

num=8
我会很高兴知道我错过了什么?
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/fcntl.h>
#include <termios.h>

int num = 0;
int y = 1;
void signal_hand(int sig) {
signal(SIGUSR1, signal_hand);
num = num + 1;
y = y * f();
}

int f() {
if (num == 2) {
return y;
}
pid_t pid = 0;
pid = getpid();
kill(pid, SIGUSR1);
return 2 * y;
}

int main(void) {
int x = 0;
signal(SIGUSR1, signal_hand);
x = f();
printf("num = %d\n", x);
return 1;

}

最佳答案

这是个有趣的问题。
所以发生的事情是创建了一个信号处理程序,它调用 f(),杀死正在运行的程序。但是信号处理程序捕获它发出的相同信号。
每次程序被终止时,它都会调用信号处理程序,并再次尝试终止该程序。这是循环自杀。这个程序真想死。
这将是一个永无止境的循环,除了它计算它捕获信号的次数,当它捕获 2 个信号时,计数为 num=2,它从 f() 返回,而不会第三次杀死自己。
所以要分解它是如何达到 8 的...
它总共调用了 f() 3 次。第一次,它被调用,它自杀了。它通过信号处理程序再调用自己 2 次。
这很难简单解释。

  • f() 调用的外层(这是开始kill递归的函数),这是最后一个f()结束,它从3)中取y=4的结果[下面]并将其乘以 2,得到 8。它返回。

  • 这调用了以下内容,它们按顺序运行:
  • f() 调用的内层(1 个信号陷阱)返回 2,然后乘以处理程序中的 y=1 得到 y=2。此函数在信号处理程序接收到第二个信号(如下)之前完成,并且是第一个完成的 f()。
  • 2) 完成后。 f() 调用的另一个内层(2 个信号陷阱)返回 2,即它开始的值。它稍后乘以 y,在信号处理程序中为 2,得到 4。此时 Num=2。这是完成的第二个 f() 。

  • 现在那些“最后”两个步骤,我认为不是按顺序运行的,我认为如果在 f() 中有更多处理,我们会看到信号将被困在陷阱 2 中,而陷阱 1仍在运行。但我认为我们在这里看到的是时间问题,陷阱 1 f() 在信号有时间发出之前立即完成,通过操作系统并返回到由信号处理程序处理的应用程序。
    这是一个邪恶的问题。我认为这个问题的重点是当你在 C 中捕获一个信号时,程序并没有死,它仍然非常活跃。它也可以被多次杀死,信号处理可以完全控制程序做什么以及如何关闭。
    举个例子说明为什么这很有用,想象一个 Linux 数据库,它习惯性地通过 SHM 或其他方式驻留在 RAM 中。如果您想关闭 PC 或其他东西,操作系统会向程序发送终止信号。大多数程序忽略这一点,然后就死了,但数据库可能无法死,因为它可能会丢失尚未写入磁盘的数据,因此在这种情况下,它可能想要捕获终止信号,然后刷新数据到磁盘,然后退出。
    *注意我在这里说的是杀死和死亡,但我刚刚注意到这是一个用户信号,但机制也与杀死信号相似。

    关于c - 信号 - SIGUSR1 类练习,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65967574/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com