2011-09-24 86 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