【问题标题】:What exactly does fork return?fork 究竟返回了什么?
【发布时间】:2011-07-31 10:59:44
【问题描述】:

成功时,孩子的 PID 进程在父进程中返回 执行线程,0 是 在子执行线程中返回。

p = fork();

我对它的手册页感到困惑,p 等于 0 还是 PID

【问题讨论】:

  • 有人可以在图片中加入getpid()吗? getpid() in child 返回 0?
  • @Shrinidhi:fork() 也是如此。
  • 它既是 pid 又是 0。当调用 fork 时,程序“分裂”成两部分——它自己和它的邪恶孪生兄弟。在原程序中为0,在evil twin程序中为pid。
  • 我相信fork 会返回一小部分食物,但我可能是错的。 ;-)
  • 有什么好混淆的?你引用的文档很清楚。

标签: c linux fork


【解决方案1】:

我不确定手册如何更清晰! fork() 创建一个新进程,因此您现在有两个相同 进程。为了区分它们,fork() 的返回值不同。在原始进程中,您获得子进程的 PID。在子进程中,你得到 0。

所以一个规范的用法如下:

p = fork();
if (0 == p)
{
    // We're the child process
}
else if (p > 0)
{
    // We're the parent process
}
else
{
    // We're the parent process, but child couldn't be created
}

【讨论】:

  • 0 也表示没有进程创建,对吧?否则进程会递归创建,永不停止...
  • @compiler: 不,两个进程(旧的和新创建的)在调用fork之后继续执行。
  • @Joachim Sauer,我的意思是没有进程创建,不是说exit
  • @compiler:没有递归。正如@Joachim 所说,新进程不是从 main 开始,而是在 fork() 调用之后直接进行。
  • 如果没有创建进程,则意味着fork失败,所以它返回-1,而不是0,并适当地设置errno。它在原始进程中执行此操作(它不是父进程,因为没有创建任何进程)。
【解决方案2】:

我认为它是这样工作的: 当pid = fork()时,代码应该被执行两次,一次在当前进程,一次在子进程。 所以它解释了为什么 if/else 都执行。 顺序是,先当前进程,再执行子进程。

【讨论】:

  • 不保证订单(据我所知)。
【解决方案3】:

Fork 创建一个重复的进程和一个新的进程上下文。当它返回 0 值时,表示子进程正在运行,但当它返回另一个值时,表示父进程正在运行。我们通常使用wait语句,让子进程完成,父进程开始执行。

【讨论】:

    【解决方案4】:

    进程在有向树中构建,您只知道您的单亲 (getppid())。简而言之,fork() 在错误时返回<strong>-1</strong>,就像许多其他系统函数一样,非零值对于 fork 调用(父)的发起者了解其新子 pid 很有用。

    没有什么比例子更好:

    /* fork/getpid test */
    #include <sys/types.h>
    #include <unistd.h>     /* fork(), getpid() */
    #include <stdio.h>
    
    int main(int argc, char* argv[])
    {
        int pid;
    
        printf("Entry point: my pid is %d, parent pid is %d\n",
               getpid(), getppid());
    
        pid = fork();
        if (pid == 0) {
            printf("Child: my pid is %d, parent pid is %d\n",
                   getpid(), getppid());
        }
        else if (pid > 0) {
            printf("Parent: my pid is %d, parent pid is %d, my child pid is %d\n",
                   getpid(), getppid(), pid);
        }
        else {
            printf("Parent: oops! can not create a child (my pid is %d)\n",
                   getpid());
        }
    
        return 0;
    }
    

    结果(在这种情况下,bash 是 pid 2249):

    Entry point: my pid is 16051, parent pid is 2249
    Parent: my pid is 16051, parent pid is 2249, my child pid is 16052
    Child: my pid is 16052, parent pid is 16051
    

    如果您需要在父子之间共享一些资源(文件、父 pid 等),请查看 clone()(对于 GNU C 库,也许还有其他)

    【讨论】:

      【解决方案5】:

      这是很酷的部分。 两者都相等。

      嗯,不是真的。但是一旦fork 返回,您现在有两个正在运行的程序副本!两个进程。您可以将它们视为替代宇宙。一、返回值为0。另一个是新进程的ID

      通常你会有这样的东西:

      p = fork();
      if (p == 0){
          printf("I am a child process!\n");
          //Do child things
      }
      else {
          printf("I am the parent process! Child is number %d\n", p);
          //Do parenty things
      }
      

      在这种情况下,两个字符串都将被打印,但通过不同的进程!

      【讨论】:

      • 你有父/子倒退。
      • @interjay:哎呀!谢谢。固定。
      【解决方案6】:
      p = fork(); /* 假设没有错误 */ /* 你现在有两个 */ /* 正在运行的程序 */ -------------------- 如果 (p > 0) { |如果(p == 0){ printf("父\n"); | printf("孩子\n"); ... | ...

      【讨论】:

        【解决方案7】:

        fork() 在父进程中被调用。然后产生一个子进程。当子进程产生时,fork() 已经完成了它的执行。

        此时,fork() 已准备好返回,但根据它是在父级还是子级中,它返回不同的值。在子进程中返回0,在父进程/线程中返回子进程ID。

        【讨论】:

        • 你的意思是fork 在子进程中计算为NO Operation
        • @compiler:在这种情况下,它没有副作用。但根据调用位置的不同,它的返回方式也不同。
        • 没有。 Fork 在父进程中运行,然后创建一个额外的进程。 fork 的返回值,在两个进程中会有所不同,然后区分两者。
        • @Noufal Ibrahim,我知道0 表示在子进程中,但这是否也意味着没有创建额外的进程?
        • 如果您调用一次fork,将创建一个进程。我不明白你的问题。
        【解决方案8】:

        一旦fork 被执行,你就有两个进程。该调用向每个进程返回不同的值。

        如果你这样做

        int f;
        f = fork();
        if (f == 0) {
          printf("I am the child\n");
        } else {
          printf("I am the parent and the childs pid is %d\n",f);
        
        }
        

        您将看到打印的两条消息。它们由两个单独的过程打印。这是您可以区分创建的两个进程的方式。

        【讨论】:

        • 返回0时,表示fork没有创建进程,对吧?
        • 没有。这意味着您处于子进程中。 “不创建进程”意味着只有一个进程。如果返回 -1,则表示没有创建子节点。手册页表明了这一点。
        • 什么时候不创建孩子?如果我在 while 循环中使用 fork(),我会得到 -1 的值吗?
        • 可能出于任何原因。 errno 如果返回 -1 就会被设置,这样你就会知道它失败的原因。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-02-11
        • 2017-05-06
        • 2016-04-21
        • 2013-06-30
        • 2011-10-11
        相关资源
        最近更新 更多