2014-11-08 128 views
1

學習爲C.等待叉孩子繼續

下面的代碼約fork()pipe()之前寫到管道創建一個管道和一個子進程。孩子發送消息,父母讀取消息。

int main() { 
    int  fd[2]; 
    pid_t pid; 
    pipe(fd); 
    pid = fork(); 
    if (pid == 0) { 
     // Child 
     close(fd[0]); 
     write(fd[1], "HELLO", (strlen("HELLO")+1)); 
     exit(0); 
    }else{ 
     // Parent 
     close(fd[1]); 
     char buffer[80]; 
     read(fd[0], buffer, sizeof(buffer)); 
     printf("Received string: %s", buffer); 
    } 
    return 0; 
} 

它工作正常。如果您對write行發表評論,則父級會報告它收到了一個帶有奇怪字符的字符串,我認爲這是正常的,因爲它正在讀取與我的程序無關的內存。

但後來,它帶來的問題:是不是有可能父閱讀管之前孩子可以寫數據?如果發生這種情況,它會讀奇怪的字符。

父母如何「等待」從孩子那裏寫入數據?

將來我可能會有幾個孩子的過程,我希望父母在繼續之前等待所有孩子完成他們的工作。

+1

檢查返回的值* *全部**這些系統調用。你看到垃圾是因爲你盲目地閱讀沒有寫入的東西。 – Mat 2014-11-08 08:55:25

+0

@Mat:什麼系統調用?你的意思是'fork()'和'pipe()'? – Voldemort 2014-11-08 09:05:45

+0

...和「讀」和「寫」。所有這些都可能失敗,即使他們沒有返回的信息對於制定正確的計劃也是必要的。 (對於失敗的「關閉」,通常你可以做的不多,但它也可能失敗。) – Mat 2014-11-08 09:09:18

回答

1

如果你對此有何評論寫行,家長會報告說,如果到write中的呼叫孩子跳過它接受一個字符串奇怪的字符

,子進程結束,孩子的寫作管端的末端關閉。

父級檢測到,孩子的管道末端已關閉,這使read()的調用返回。父母實際上沒有讀任何東西,所以緩衝區保持未初始化並且「垃圾」被打印出來。

請找到下面read's POSIX specification的relvant部分:

當試圖從一個空的管道或FIFO讀:

  • 如果沒有進程打開寫作的管道,閱讀()應返回0表示文件結束。

[...]

  • 如果某些進程打開了寫作的管道和O_NONBLOCK清晰,閱讀(),直到一些數據被寫入或管道被關閉,應阻塞調用線程所有的管道都可以寫入。

爲了使你的代碼來處理孩子的情況下,不寫任何東西,測試是否父爲「調用read()`真的讀的東西:

  ssize_t result = read(fd[0], buffer, sizeof(buffer)); 
      if (-1 == result) /* Also ALWAYS test for error. */ 
      { 
       perror("read() failed"); 
      } 
      else if (0 == result) 
      { 
       fprintf(stderr, "read() returned without having read anything.\n") 
      } 
      else 
      { 
       printf("Received string: '%s'", buffer); 
      }