在 for 循环中 fork

标签 fork unix

我对以下代码及其行为有疑问:

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

#define N 5
#define nt 1

int pm[N][2],pid[N];
int i,j,size;
char s[100];
int count=0;

int main()
{
 for(i=1;i<N;i++)
    {
      printf("\n i=%d",i);

      if(pid[i]=fork() == -1)
        {
          printf("\n fork not wrking");
          exit(1);
        }
      else if(pid[i]>0)
        {
          printf(" \n pid:%3d\n",pid[i]);
        break;
        }

    }
return 0;
}

我最初认为代码会产生一个进程并跳出循环。
从而,
1 产生 2 并跳过。
2 生成 3 并跳过
3 生成 4 并跳过
4 产生 5 并跳过。

我尝试执行此代码,但对我得到的答案感到惊讶(对于代码中 i 的 printf)。这是输出
 i=1
 i=2
 i=3
 i=2
 i=4
 i=3
 i=3
 i=3
 i=4
 i=4
 i=4
 i=4
 i=4
 i=4
 i=4

任何人都可以向我解释这里发生了什么。
注意:我在 Solaris 机器上工作。

最佳答案

更新

您在更新的代码中缺少一组括号。那应该是 if ((pid[i] = fork()) == -1)不是 if (pid[i] = fork() == -1) !

后者相当于if (pid[i] = (fork() == -1))由于优先规则。它最终将 0 分配给 pid[i]每次通过循环,所以 parent 认为他们是子进程并且不会跳出循环。

我同意你对应该发生什么的分析。 parent 应该产生一个 child 然后退出,所以每个 i=n打印输出应该只出现一次。

您确定您完全按照问题中的说明输入了吗?我运行了你的程序(稍作修改)并得到了你预测的输出:

$ cat fork.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

#define N 5

int main() {
    int pid[N], i;

    for(i=1;i<N;i++) /* What’s the total number of processes? */
    {
    printf("i=%d\n",i); // Output of all the is
    if((pid[i]=fork())==-1) exit(1);
    else if(pid[i] > 0) break;
    }

    return 0;
}
$ gcc -o fork fork.c
$ ./fork
i=1
i=2
$ i=3
i=4

请注意,我移动了 \n在打印输出到最后。当你把它放在行首时,你会得到 stdout没有被刷新,所以当父进程和子进程都刷新它们的输出缓冲区时,你会得到多个打印输出。这可能是您的问题的原因。 FWIW 在我的 Mac 上,我每次打印输出两次。

关于在 for 循环中 fork,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2256357/

相关文章:

相当于 solaris 的 fork1 的 Linux

c - 帮助在 C 中实现 GNU Readline

c - fork() 和二叉树创建

c/fork/signals/关闭不同进程中打开的套接字的最佳实践

c - 如何在 Ubuntu 上打开一个非修饰的全屏窗口

unix - 使用 openSSL 验证 EU GreenPass

c - pipe() 从 1 个父进程到单独的 c 文件中的多个子进程

linux - bash 中的高级 printf 解释

unix - pstree 中进程周围的花括号是什么意思?

c++ - 独立于平台的图形用户界面