2014-10-11 103 views
3

我是fork(),父進程和子進程的新手,並且難以理解我編寫的代碼背後的邏輯,但是沒有執行I預期。以下是我有:Fork()新進程並寫入子進程和父進程的文件

int main (int argc, char** argv) 
{ 
    FILE *fp_parent; 
    FILE *fp_child; 

    fp_parent = fopen ("parent.out","w"); 
    fp_child = fopen ("child.out","w"); 

    int test_pid; 
    printf ("GET HERE\n"); 

    fprintf (fp_parent,"Begin\n"); // MY CONCERN 

    for (int i = 0; i < 1; i++) //for simplicity, just fork 1 process. 
    {       // but i want to fork more processes later 
     test_pid = fork(); 
     if(test_pid < 0) 
     { 
      printf ("ERROR fork\n"); 
      exit (0); 
     } 
     else if(test_pid == 0) // CHILD 
     { 
      fprintf(fp_child,"child\n"); 
      break; 
     } 
     else //PARENT 
     { 
      fprintf(fp_parent,"parent\n"); 
     } 
    } 
    fclose(fp_parent); 
    fclose(fp_child); 
} 

所以上面代碼的輸出是:

to stdout: GET HERE 

in parent.out: 

Begin 

parent 

Begin 

in child.out: 

child 

我主要擔心的是,我不明白爲什麼「開始」被寫入到parent.out兩次。如果我完全刪除了for循環,那麼只有一個「開始」被寫入預期。

所以我認爲,這是因爲fork(),肯定我想念或不理解它背後的一些邏輯。你能幫我解釋一下嗎?

我打算在parent.out的for循環之前寫一些東西,並在parent.out的for循環中寫一些東西。子進程將寫入child.out。

回答

4

在C中,使用FILE結構的輸入/輸出操作在用戶進程級別進行緩衝。在你的情況下,你寫到fp_parent的輸出實際上沒有寫到磁盤上,並且在fork時刻保存在本地緩衝區中。 fork創建整個過程的副本,其中包含含有Begin的緩衝區,這就是爲什麼它會在文件中出現兩次。嘗試在fork之前放fflush(fp_parent);。這將刷新緩衝區,髒行將從文件中消失。

+0

fflush作品。但我試圖在fprintf後插入同步,並得到相同的結果(加倍從parent.out開始)。爲什麼這不起作用? – 2014-10-11 09:13:55

+0

並且你可以指定這個緩衝區位於內核空間的位置嗎? – 2014-10-11 09:15:58

+1

這與內核沒有任何關係。使用'FILE'的I/O在標準庫中進行緩衝,該庫與代碼連接,並提供可執行程序。這意味着它與您自己的代碼自己緩衝它在同一級別上發生。緩衝區由程序在您的程序地址空間中進行物理分配,這就是爲什麼它們被'fork'複製的原因。如果您不想使用這些緩衝區,請使用不帶'f'的I/O函數,即「open」,「write」,「close」。 – Marian 2014-10-11 09:23:46