【问题标题】:Using fork and kill signals使用 fork 和 kill 信号
【发布时间】:2014-01-02 13:13:15
【问题描述】:
int main() {
    int pid = fork();
    if(pid > 0){
        kill(pid, SIGKILL);
        printf("a");
    }else{
        /* getppid() returns the pid
        of the parent process */
        kill(getppid(), SIGKILL);
        printf("b");
    }
}

代码片段的结果可能是:nothing, a, b, ab, ba

我不明白为什么什么都不可能,ab 和 ba。

int a = 1;
void handler(int sig){
    a = 0;
}
void emptyhandler(int sig){
}
int main() {
    signal(SIGINT, handler);
    signal(SIGCONT, emptyhandler);

    int pid = fork();
    if(pid == 0){
        while(a == 1)
            pause();
        printf("a");
    }else{
        kill(pid, SIGCONT);
        printf("b");
        kill(pid, SIGINT);
        printf("c");
    }
}

这个结果是 bac, bca。

我不确定为什么“进程不会终止”也有效?为什么 SIGINT 会杀死它?

【问题讨论】:

    标签: c signals fork kill


    【解决方案1】:

    不知道哪个孩子/父母先运行。或者,如果您有多个核心,它们可能会并行运行,或者操作系统可能会在任何执行点中断它们并运行另一个子进程或父进程(或其他一些完全不同的进程)。 kill() 也是异步的,它发送信号,可能会在 kill() 返回后由接收方处理。

    什么都没有:父级在执行kill(pid, SIGKILL); 后立即被杀死。孩子做完就被杀了kill(getppid(), SIGKILL);

    “a”:孩子在kill(getppid(), SIGKILL); 之前或之后被杀死。父母可以运行到完成。

    "b":父母在kill(pid, SIGKILL); 之前或之后被杀死。孩子可以跑完。

    "ab" 父级在打印“a”后立即被杀死(或者它可能在子信号到达之前运行完成),子级在打印“b”后被杀死(或也许它设法在父信号到达之前完成)

    “ba”与“ab”大小写相同,只是安排孩子先打印“b”。

    【讨论】:

    • 对于我刚刚添加的第二个 sn-p,kill(pid,SIGINT) 是做什么的?谢谢你的第一部分顺便说一句。
    • 它向进程发送 SIGINT 信号。 SIGINT 与按 CTRL+C 时发送的信号相同。默认情况下,该信号终止进程。
    • 在这个作业问题中,“进程不会终止”仍然是一个选项。如果有 SIGINT 调用,那怎么可能?
    • @NeilBharatPatel 您的代码没有为 SIGINT 安装处理程序吗?该处理程序似乎没有终止该过程。因此默认处理程序(将终止进程)不会运行,因为您已经替换了它。
    【解决方案2】:

    发送信号并不构成两个进程之间的任何同步。只有发送接收信号才能让您得出结论,某事(例如打印a)发生在其他事情之后(例如打印b)。这两种信号都可以“在飞行中”,并且不会被任何人接收到。

    【讨论】:

    • 飞行中被称为pending
    • @Jean-BaptisteYunès:我认为“待定”是“飞行中”的严格子集,但由于缺乏指定的全局同步语义,因此很难比这更精确。
    • 您能解释一下什么是未挂起的飞行信号吗?
    • @Jean-BaptisteYunès:假设内核正在从数百个内核上运行的数千个进程接收数百万个信号。我想kill 调用可能会在内核实际在目标进程的控制结构中注册信号(或决定哪个线程将接收信号)之前返回,以便目标可以通过sigpending 知道信号。但正如我所说,如果不保证操作系统是可序列化的(我不相信这是给定的),很难做到这一点。
    • 好吧,你的意思是理论上是可以的。我可能是错的,但我认为这是一种不常见的 posix 语义解释,并且可能是不正确的解释。 kill 保证验证是否可以发送,等等,如果在验证条件后信号不会被有效发送,我会很奇怪......如果你是对的,如果信号的传递可以通知发送者交付是异步的?
    猜你喜欢
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-20
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    相关资源
    最近更新 更多