创建多个子进程时出现问题
我在流程创建等方面是新手。所以可能是一个基本问题。
我创建了固定数量的子进程,每个子进程除了打印它们的 pid 之外什么也不做。问题出在我得到的输出中。看一下:
int main(){
pid_t pid=0;
int i=0,status=0;
for(i=0;i<3;i++){
pid=fork();
switch(pid){
case 0:{ //Child
printf("\nChild pid: %d",getpid());
exit(0);
break;
}
case -1: {//Error
printf("Error occured in fork");
exit(1);
break;
}
default:{
printf("\nParent id: %d",getpid());
printf("\nIts child id: %d",pid);
wait(NULL);
}
}
输出:子进程 pid:1450
家长 ID:1445
其子 ID:1450
子进程 pid: 1455它的子进程 id: 1450
家长 ID:1445
其子 ID:1455
孩子 pid: 1460 孩子 id: 1455
家长 ID:1445
它的子id:1460
问题是我不知道为什么只出现父进程的第二个打印语句而不是第一个(如果有的话)。我知道我不等待我的子进程结束(坦率地说,我不知道我会怎么做),但是如果父进程在结束其子进程之前执行,为什么它的两个打印语句都没有出现,以及为什么 \n
在该行中也被忽略。
任何帮助将不胜感激。
谢谢。
更新:如果我将 wait(NULL)
替换为 printf("\n%d\n",wait(NULL))
它会给我一个完美的输出,没有杂散的打印。知道什么可以修复它吗?毕竟他们都做同样的事情。
Im new at process creation etc..so probably a basic question.
Im creating a fixed number of child processes, each doing nothing but printing their pid. The problem is in the output that i get. Have a look:
int main(){
pid_t pid=0;
int i=0,status=0;
for(i=0;i<3;i++){
pid=fork();
switch(pid){
case 0:{ //Child
printf("\nChild pid: %d",getpid());
exit(0);
break;
}
case -1: {//Error
printf("Error occured in fork");
exit(1);
break;
}
default:{
printf("\nParent id: %d",getpid());
printf("\nIts child id: %d",pid);
wait(NULL);
}
}
Output:Child pid: 1450
Parent id: 1445
Its child id: 1450
Child pid: 1455Its child id: 1450
Parent id: 1445
Its child id: 1455
Child pid: 1460Its child id: 1455
Parent id: 1445
Its child id: 1460
The problem is I dont know why only the second print statement of the parent process is appearing and not the first, if any at all. I know im not waiting for my child processes to end( frankly i dont know how i would do that), but if the parent does execute before ending its child processes, why arent both its print statements appearing, and why is the \n
being ignored in that line too.
Any help would be greatly appreciated.
Thx.
Update:If i replace wait(NULL)
with printf("\n%d\n",wait(NULL))
It gives me a perfect output, without stray prints. Any idea what couldve fixed it? After all they both do the same thing.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题是有多个进程同时写入同一个文件(您的控制台),没有任何并发控制或任何锁定。而且ttys是奇怪的生物,充其量只能让奇怪的事情发生。除此之外,请记住
printf
是有缓冲的。您的输出应该这样阅读:
您可以尝试将输出重定向到文件,并查看不是 tty 是否有任何区别。
无论如何,为了正确地做到这一点,您应该使用任何保证多进程正确性的机制。
更新
是的,现在我明白了。 '\n' 位于打印行的开头,而不是像往常一样位于末尾。标准输出通常是行缓冲的,这意味着当看到“\n”时,缓冲区将刷新到设备。由于一开始就拥有它们,因此缓冲区中始终有一行等待输出。
现在,当您
fork
您的进程时,输出缓冲区会被复制,并且子进程会打印父进程的最后一行(为什么它在之后打印,而不是之前,是对我来说仍然是个谜)。无论如何,您添加的新
printf
末尾有一个 '\n',因此它会刷新缓冲区,fork
发现它为空,一切正常。您也可以调用 fflush(stdout) ,但这很麻烦。这个故事的主旨是:“当你
printf
出于调试目的总是在每行末尾放置一个\n
,否则你可以得到部分的、混合的内容。The problem is that there are several processes writing to the same file (your console) at the same time without any concurrency control or any lock. That, and that the ttys are strange creatures, at best, make weird things happens. Over that, remember that
printf
is buffered.Your output should be read this way:
You could try redirecting the output to a file, and see if not being a tty makes any difference.
Anyway, to do it the right wat, you should use any mechanism that guarantees multiprocess correctness.
UPDATE
Yes, now I see it. You have the '\n' at the beginning of your printing lines, not at the end, as is usual. Stdout is normally line-buffered, that means that the buffer is flushed to the device when it sees a '\n'. And since you have them at the beginning there is always one line in the buffer waiting for output.
Now, when you
fork
your process the output buffer gets duplicated and the last line from the parent is printed by the child (why it is printed after, and not before, is still a mystery to me).Anyway, the new
printf
you added has a '\n' at the end, so it flushes the buffer,fork
finds it empty and all goes fine. You could as well callfflush(stdout)
but it is cumbersome.The morale of the story is: "When you
printf
for debugging purposes always put a\n
at the end of every line or you can get partial, mixed contents.问题是标准输出的缓冲和刷新。
这两行都被打印,但没有在您期望的时间刷新到输出......取决于输出的位置,(文件、管道、终端、stderr 等) printf 使用不同的缓冲区策略。
我想在你的情况下,它只会在换行符上刷新(检查
man setbuf
)将换行符移动到末尾而不是开头,所以例如....
并与始终放置保持一致所有 printf 的 printf 末尾的 \n 。
The problem is buffering and flushing of stdout.
Both lines are being printed, but not flushed to output at the time you expect.... depening on where the output is going to, (file, pipe, terminal, stderr etc) printf uses different buffer strategies.
I guess that in your case it only flushes on newline (check
man setbuf
)Move the newline to the end of the rather than in the beginning, so for example....
And be consistent with alway putting the \n at the end of printf for all your printfs.