创建多个子进程时出现问题

时间:2011-09-24 10:56:21

标签: linux shell process

我是创造过程的新手......也许是一个基本问题 我创建了固定数量的子进程,每个进程除了打印他们的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);
                            }
            }

输出:
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

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

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

2 个答案:

答案 0 :(得分:1)

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

您的输出应以这种方式阅读:

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会有什么不同。

无论如何,要做正确的扫描,你应该使用任何保证多进程正确性的机制。

<强>更新

是的,现在我明白了。您通常会在打印行的开头有“\ n”,而不是最后一行。 Stdout通常是行缓冲的,这意味着缓冲区在看到'\ n'时会刷新到设备。而且由于你在开头有它们,缓冲区中总有一行等待输出。

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

无论如何,你添加的新printf最后有一个'\ n',所以它刷新缓冲区,fork发现它为空,一切正常。你也可以打电话给fflush(stdout),但这很麻烦。

故事的士气是:“当您printf进行调试时总是在每行的末尾添加\n,或者您可以获得部分混合内容

答案 1 :(得分:0)

问题在于缓冲和刷新标准输出。

两行都在打印,但没有刷新到你想要的时间输出....取决于输出的位置,(文件,管道,终端,stderr等)printf使用不同的缓冲策略。

我想在你的情况下它只会在换行符上刷新(检查man setbuf

将换行符移到末尾而不是开头,例如......

       printf("Parent id: %d\n",getpid());
       printf("Its child id: %d\n",pid);

并且始终将\ n放在printf的末尾,用于所有printfs。