我对以下代码及其行为有疑问:
#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/