2015-10-05 56 views
1

我想在C中的一個子作家和一個父閱讀器之間建立一個管道。 我認爲我的父進程必須等待它的子進程才能夠讀取它,然後我要檢查它,所以我寫了下面的代碼:父進程中的read()是否等待管道中的子寫()?

pipe(fd); 
// ... checks for pipe 
pid_t pid = fork(); 
// ... checks for fork 
if (pid == 0) { 
    close(fd[0]); 
    // Long sleep hoping parent will terminate before the write() 
    sleep(10); 
    write(fd[1], "hello", strlen("hello") + 1); 
    close(fd[1]); 
} else { 
    close(fd[1]); 
    read(fd[0], buf, sizeof(buf)); 
    printf("received: %s\n", buf); 
    close(fd[0]); 
} 
return 0; 

輸出是意外(或不是嗎?)received: hello。 如果我用for (volatile int i = 0; i < some_big_int; ++i);循環將呼叫替換爲sleep(),則輸出相同。 我不認爲調用read()會阻止我的父進程,直到子進程在管道的另一端寫入,但我無法解釋這種行爲。任何提示?

+1

這是預期的操作:I.E. 'read()'塊,將在所請求的總字節數被讀取或遇到eof時返回。或某些錯誤事件和信號 – user3629249

+0

我無法找到「man 2 read」中所說的內容:例如這個句子似乎表明,如果沒有什麼要讀,read()返回並且是非阻塞的:'在沒有任何錯誤的情況下,或者如果read()不檢查錯誤,則read() 0返回零並且沒有其他效果。' – hdl

+1

當'read'在流fd(例如管道)上傳遞非零count時,它會阻塞,直到至少有1個字節可用,然後讀取'計數「,因爲它可以在那個時候。既然你寫了'close'(寫入小於'PIPE_BUF'),它會立即刷新整個字符串,所以當它解除封鎖時,它會立即寫入所有內容。 – ShadowRanger

回答

2

read將阻塞,直到至少有一個字節要讀取,或遇到錯誤,或者到達流的末尾。當至少有一個字節要讀取時,它將讀取儘可能多的字節(最多可指定的最大數量),然後返回。

在這種情況下,父進程對read的調用將阻塞,直到子進程write對管道有某種東西。


man 7 pipe上管和FIFO I/O:

如果一個進程試圖從空管到讀,然後讀(2)將阻塞,直到可用的數據。如果一個進程試圖寫入一個完整的管道(見下文),那麼寫入(2)塊直到從管道讀取足夠的數據以允許寫入完成。通過使用fcntl(2)F_SETFL操作來啓用O_NONBLOCK打開文件狀態標誌,可以實現非阻塞I/O。

+0

這是在哪裏指定的?不幸的是,我的ID沒有在'man 2 pipe'和'man 2 read'中找到這個信息。 – hdl

+0

在'man 7 pipe'中找到它,並相應地編輯你的答案。非常感謝你。 – hdl

相關問題