2011-09-24 44 views
0

进程创建等问题,我可能是一个基本问题。
我创建了一个固定数量的子进程,每个进程只是在打印他们的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语句中出现,而不是第一个,如果有的话。我知道我不等待我的子进程结束(坦率地说,我不知道我会怎么做),但是如果父进程在结束它的子进程之前执行,为什么不出现它的打印语句,为什么\n被忽略也在那一行。
任何帮助将不胜感激。
Thx。

更新:如果我将wait(NULL)替换为printf("\n%d\n",wait(NULL))它给了我一个完美的输出,没有杂散打印。任何想法可以解决它?毕竟他们都做同样的事情。

回答

1

问题是,有几个进程同时写入同一个文件(您的控制台),没有任何并发​​控制或任何锁定。那,而且这些怪物是奇怪的生物,至多会发生奇怪的事情。在此之上,请记住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有什么差别。

无论如何,要做到这一点,你应该使用任何机制来保证多进程的正确性。

UPDATE

是的,现在我看到它。您的印刷线一开始就有'\ n',而不是像往常一样结束。标准输出通常是行缓冲的,这意味着缓冲区在看到'\ n'时被刷新到设备。而且由于你在开始时有它们,所以缓冲区中总是有一行等待输出。

现在,当你fork的过程中,输出缓冲器被复制,并从父最后一行是由孩子打印(为什么它被后打印,而不是之前,仍是一个谜给我)。

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

故事的士气是:“当你printf用于调试目的总是\n在每行的末尾或者你可以得到部分,混合内容

+0

好的,我不会等待子进程的帮助吗?如果那样,你能否解释我将如何做到这一点? – Urban

+0

但是你*正在等待,请看'wait()'函数调用。有了孩子pid,我个人更喜欢'waitpid()',以防万一。 – rodrigo

+0

是的,我确实把这一点,但我真的不知道,如果这是放在正确的地方,或者如果itll工作even..thx反正。 – Urban

0

的问题是缓冲和冲洗。 stdout

两行都正在打印,但不会在您期望的时间输出。取决于输出的位置,(文件,管道,终端,stderr等)printf使用不同的缓冲策略。

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

移动换行来的,而不是在一开始就结束,因此,例如....

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

并且始终将\ n放在所有printf的printf结尾处。

+0

THX解释说......不知道这个.. – Urban