for 循环中的 fork
我对下面的代码及其行为有疑问:
#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 计算机上工作。
I have a doubt in the following piece of code and its behaviour:
#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;
}
I initially thought that the code will spawn a process and skip out of the loop.
Thereby,
1 spawns 2 and skips out.
2 spawns 3 and skips out
3 spawns 4 and skips out
4 spawns 5 and skips out.
I tried executing this code and was surprised by the answer i got ( for the printf of i in the code). Here is the output
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
Can Anyone please explain to me what is going on here.
NOTE: I am working on a Solaris machine.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
更新
您更新的代码中缺少一组括号。这应该是
if ((pid[i] = fork()) == -1)
而不是if (pid[i] = fork() == -1)
!由于优先级规则,后者相当于
if (pid[i] = (fork() == -1))
。每次循环时它都会将 0 分配给 pid[i],因此父进程认为它们是子进程并且不会跳出循环。我同意你对应该发生什么的分析。父进程应该生成一个子进程,然后退出,因此每个
i=n
打印输出应该只显示一次。您确定您输入的内容与您的问题中指定的完全一致吗?我运行了您的程序(稍加修改)并得到了您预测的输出:
请注意,我将打印输出中的
\n
移到了末尾。当您将其放在行的开头时,最终 stdout 不会被刷新,因此当父进程和子进程都刷新其输出缓冲区时,您会得到多个打印输出。这可能是你的问题的原因。 FWIW 在我的 Mac 上,每个打印输出都有两次。Update
You're missing a set of parentheses in your updated code. That should be
if ((pid[i] = fork()) == -1)
notif (pid[i] = fork() == -1)
!The latter is equivalent to
if (pid[i] = (fork() == -1))
due to precedence rules. It ends up assigning 0 topid[i]
each time through the loop, so the parents think they are child processes and don't break out of the loop.I agree with your analysis of what should happen. The parent should spawn a child and then quit, so each
i=n
printout should only show up once.Are you sure you typed it in exactly as specified in your question? I ran your program (with minor modifications) and got the output you predicted:
Note that I moved the
\n
in the printout to the end. When you put it at the beginning of the line you end up withstdout
not being flushed, so you get multiple printouts when the parent and child processes both flush their output buffers. That might be the cause of your problem. FWIW on my Mac I got each printout twice.Fork 创建一个重复的进程,包含父进程所做的一切,包括文件句柄等。唯一的区别是 fork() 的返回值:父进程看到 pid,子进程看到零。
第一次迭代创建第一个子项。它的
i
副本也是 1,与父级相同。孩子挣脱了循环。当我运行它时,我得到了与你不同的结果:Fork creates a duplicate process, containing everything the parent does, including file handles, etc. The only difference is the return value of fork(): the parent sees the pid, the child sees zero.
The first iteration creates the first child. Its copy of
i
is also 1, same as parent. The child breaks out of the loop. I get different results from you when I run it:你使用什么风格的 Unix? fork 是否有可能不返回 int ?
在这种情况下,pid[i]> 0 比较可能会失败。
What flavor of Unix are you using. Is there any chance fork isn't returning an int?
In that case the pid[i] > 0 compare might fail.
该表达式
不会达到您的预期。你可能想说
The expression
won't do what you expect. You probably meant to say
每个子进程在生成时都会使用
i
的当前值继续循环。结果,第一个进程打印i
1,然后生成一个子进程。接下来,这两个进程都会打印i
2 并生成一个子进程,总共有四个进程。所有四个进程都打印i
3,并且每个进程都会生成一个新进程,最后,所有 8 个进程都打印值 4。编辑: 抱歉,我忽略了这一部分父级应该退出循环的地方。至于为什么没有发生这种情况,可能是因为 PID 存储为有符号整数,但足够高以传递最大有符号值,使其成为负值。如果您进行此替换,它会起作用吗?
到
Each child process is continuing the loop with the current value of
i
when spawned. As a result, the first process prints ani
of 1 and then spawns a child. Next, both of those process print ani
of 2 and spawn a child, for a total of four processes. All four of those print ani
of 3 and each spawn a new process, and finally, all 8 processes print a value of 4.EDIT: Sorry, I overlooked the part where the parent was supposed to be exiting the loop. As for why that's not happening, it might be because the PID is stored as a signed integer but is high enough to pass the maximum signed value, making it negative. Does it work if you make this replacement?
to