调用“getpid()== fork()”时应该返回什么

时间:2017-11-10 22:28:18

标签: c unix

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char **argv) {
    printf ("%d", getpid() == fork());
    return 0;
}

此程序的输出为00。我不太明白为什么0被打印两次。我理解在调用fork()之后,会创建一个子进程。现在两个流程都继续运行该计划的下一行。这是否意味着子进程将运行return 0?我可以看到,如果它是00,我将获得fork() == getpid()。谢谢!

2 个答案:

答案 0 :(得分:6)

fork不会导致子进程跳转到“下一行”。假设操作成功,fork 函数调用将返回两次,每次进程一次。因此,两个进程都执行与getpid的比较。

此外,C标准没有规定对getpid的调用是否在调用fork之前发生(在这种情况下只发生一次)或之后(在这种情况下它发生两次,返回两个不同的值),但结果并不重要,因为所有可能的情况都会导致比较为假:

  • fork失败:没有创建新进程并且它向父进程返回-1,这不是有效的进程ID,因此无法比较{{1}返回给父进程的值}}。 getpid之前或之后getpid是否发生并不重要,因为在任何一种情况下它都是相同的过程。

  • fork成功:它将子进程ID返回给父进程,并向子进程返回零。

    • 子进程ID不能等于父进程ID(因为它们都在同一时间运行),因此,在父进程中,比较将始终为false,并不重要fork是在getpid之前还是之后发生,因为在任何一种情况下都是相同的过程。

    • 如果fork调用发生在getpid之前,则子项将与父进程ID进行比较;如果它发生在fork之后,则孩子将零与孩子的进程ID进行比较。零也不是有效的进程ID,因此无论如何比较都是错误的。

fork是POSIX认为不会失败的极少数系统调用之一,所以我们不必担心这种可能性。

因此,此程序可以打印的唯一内容是getpid(如果0失败)或fork(如果00成功)。

我强烈建议不要在真实的程序中写这样的东西。具有“异常”控制流行为的操作(如fork)应始终作为独立语句完成,因为这使程序更易于人类阅读。你可能还没有意识到这有多重要,所以让我给你留下一个练习:重读你三个多月前写的一个程序,并试着记住它的作用和原因。 (如果你没有编程足够长的时间来做这件事,请在可以做的时候记下来做这个练习。)

答案 1 :(得分:5)

fork documentation

fork()在父进程和子进程中都返回时,它会在调用fork()系统调用结束后立即返回。它可能就像这里的情况一样位于行的中间 - 您返回表达式fork()的值并使用该值继续评估包含它的表达式 - 在这种情况下 - 是一个条件printf

fork()返回父进程中子进程的PID或子进程中的0(或出错时为-1)。

在这种情况下,两个进程都具有条件​​getpid() == fork()返回0(false),因为在父进程中,getpid()fork()返回的值不同,因为它是父进程pid(不是孩子的)和孩子 - fork返回0,这是非法的PID,getpid()无法返回。

因此00输出。