【问题标题】:Understanding how waitpid works with signals了解 waitpid 如何处理信号
【发布时间】:2020-11-15 12:29:34
【问题描述】:

考虑以下伪 C 代码:

static int G = 0;
void alrm_handler(int signo) {
    G = 1;
}

void son() {
    struct sched_param param;
     param.sched_priority = 50;
    sched_setscheduler(getpid(),SCHED_FIFO, &param);
    kill(getppid(), SIG_ALRM);
    sched_yield();
    printf("A\n");
    while(1);
    exit(0);
}

int main() {
    signal(SIG_ALRM, alrm_handler);
    int son_pid = fork();
    if(son_pid==0)
        son();
    waitpid(son_pid);
    printf("B\n");
    return 0;
}

它来自操作系统的考试。问题如下:

In multi cores CPU what would be printed?

答案是我们无法知道,因为它可能是A,然后是BB,然后是A。我不明白为什么。如果父级正在用waitpid 等待子级,而子级发送信号SIG_ALRM 为父级调用alrm_handler 函数,则父级将完成函数的执行,然后返回等待子,直到他完成运行,不?所以应该是A,然后是B

【问题讨论】:

  • “儿子”正在无限循环。所以它将是 A 后面没有任何内容,因为“儿子”进程永远运行。
  • 这是我的想法,但答案是我们不知道。我唯一的猜测是waitpid 不会等他儿子完成
  • 为什么 waitpid 不等待?还要注意waitpid(而不是wait)有一个选项等待(你的伪代码在这里没有帮助)。
  • 是的,我同意。我只是想弄清楚问题的作者是什么意思。据我了解,waitpid 将等待它获得一些价值。

标签: process signals fork system-calls


【解决方案1】:

根据 POSIX,未定义在调用 signal 设置的信号处理程序后是否重新启动系统调用。

  • System V 和 Linux signal 系统调用不会重新启动系统调用。
  • BSD 和默认情况下 GLibc 会重新启动系统调用。

如果使用 System V signal waitpid 可以在信号发送后立即返回,允许以任何顺序打印字母。如果标准输出是管道或常规文件,则只会输出B,因为子进程处于无限循环中

对于 BSD signal,只有 A 将被打印为 waitpid 由于子进程中的无限循环而不会返回。如果标准输出是管道或常规文件,则不会输出任何内容。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-14
    相关资源
    最近更新 更多