创建多个子进程的问题 [英] Problem creating multiple child processes

查看:66
本文介绍了创建多个子进程的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是流程创建方面的新手,所以可能是一个基本问题.
我创建了固定数量的子进程,每个子进程除了打印它们的 pid 什么都不做.问题出在我得到的输出中.看看:

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);
                            }
            }

输出:
子进程号:1450
父 ID:1445
它的子ID:1450
子id:1455它的子id:1450
父 ID:1445
它的子ID:1455
子id:1460它的子id:1455
父 ID:1445
它的子ID:1460

问题是我不知道为什么只出现父进程的第二个打印语句而不是第一个,如果有的话.我知道我没有等待我的子进程结束(坦率地说,我不知道我会怎么做),但是如果父进程在结束其子进程之前确实执行了,为什么它的打印语句没有出现,为什么 \n 在该行中也被忽略.
任何帮助将不胜感激.
谢谢.

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.

更新:如果我用 printf("\n%d\n",wait(NULL)) 替换 wait(NULL) 它给了我一个完美的输出,没有杂散打印.知道什么可以修复它吗?毕竟他们都做同样的事情.

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.

推荐答案

问题是有多个进程同时写入同一个文件(您的控制台),没有任何并发​​控制或任何锁定.那,而且 ttys 是奇怪的生物,充其量会使奇怪的事情发生.在此之上,请记住 printf 是缓冲的.

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.

你的输出应该这样读:

Child pid: 1450    <- Child #1
Parent id: 1445    <- Parent #1.1
Its child id: 1450 <- Parent #1.2

Child pid: 1455[Its child id: 1450] <- Child #2 with garbage at the end
Parent id: 1445                     <- Parent #2.1
Its child id: 1455                  <- Parent #2.2

Child pid: 1460[Its child id: 1455] <- Child #3 with garbage at the end
Parent id: 1445                     <- Parent #3.2
Its child id: 1460                  <- Parent #3.2

您可以尝试将输出重定向到文件,看看不是 tty 是否有任何区别.

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.

更新

是的,现在我明白了.'\n' 出现在打印行的开头,而不是像往常一样的末尾.标准输出通常是行缓冲的,这意味着缓冲区在看到 '\n' 时会刷新到设备.而且由于您在开始时拥有它们,因此缓冲区中总是有一行等待输出.

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.

现在,当你fork你的进程时,输出缓冲区被复制,父进程的最后一行由子进程打印(为什么它在之后打印,而不是之前,对我来说仍然是个谜).

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).

无论如何,您添加的新 printf 末尾有一个 '\n',因此它会刷新缓冲区,fork 发现它是空的,一切正常.你也可以调用 fflush(stdout) 但它很麻烦.

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 call fflush(stdout) but it is cumbersome.

这个故事的精神是:当你 printf 用于调试目的时总是在每一行的末尾放置一个 \n 或您可以获得部分、混合的内容.

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.

这篇关于创建多个子进程的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆