2017-03-16 50 views
1

我有一段代碼,我正在使用管道進行父和子進程之間的雙向讀寫操作。管道上的read()沒有被阻塞

從我讀過的內容來看,如果我不使用O_NONBLOCK,讀取應該阻塞,直到數據從另一端寫入管道。

但是,我注意到在父側的讀取沒有阻塞。我知道,因爲我正在gdb中進行調試,所以我已經將睡眠作爲第一條語句放在孩子的內部。

爲什麼read()by parent不在這裏阻塞?另外,還有什麼我需要做的以在兩個進程之間同步下面的讀/寫?

typedef struct 
{ 
    int x; 
    int y; 
}PayLoad; 

PayLoad pl; 
bool b = false; 

int pipe_fds[2]; 


void p(int i, int j) 
{ 
    pl.x = i; 
    pl.y = j; 

    pipe(pipe_fds); 
    pid_t cpid = fork(); 

    if (cpid == 0) // child process 
    { 
     std::this_thread::sleep_for(std::chrono::seconds(100)); // just for debugging 
     close(pipe_fds[1]); 
     read(pipe_fds[0], &pl, sizeof(Payload)); 
     //... do some processing on read data 

     close(pipe_fds[0]); 
     write(pipe_fds[1], &b, sizeof(bool)); 
     close(pipe_fds[1]); 
    } 
    else if (cpid > 0) // parent process 
    { 
     close(pipe_fds[0]); 
     write(pipe_fds[1], &pl, sizeof(Payload)); 
     close(pipe_fds[1]); 
     read(pipe_fds[0], &b, sizeof(bool)); <------ did not block! 
     close(pipe_fds[0]); 
    } 
} 
+0

它返回什麼?檢查返回值!並且不要標記c,當它真的是C++時。 –

+0

謝謝。只需添加代碼來檢查目前的閱讀回報。 – user2930006

+4

您在閱讀之前關閉描述符 - 實際上,體面的錯誤處理會爲您節省一些時間 - 並且將來也會如此。 –

回答

1

如果設置了O_NONBLOCK,則read()將返回-1並將errno設置爲[EAGAIN]。

真正的問題是您在使用它們之前關閉文件描述符。例如,在子進程中,您正在關閉pipe_fds [1],並且正在使用它來寫入一些值。在父進程中,您正在關閉pipe_fds [0],並且正在使用它讀取某個值。一旦進程關閉文件描述符,進程就不應該使用它來讀或寫。通常,管道概念是一個進程(父進程或子進程)將使用管道創建的文件描述符之一進行寫入,而另一進程(父進程或子進程)將使用另一個文件描述符來讀取數據。

+0

謝謝Erki A和kadina。確實描述符正在關閉。讀取器在讀取之前首先關閉管道的寫入端,並且在寫入之前同樣寫入器關閉管道的讀取端。但是,對於上面的場景,我應該做些什麼?在哪裏使用相同的管道,讀者隨後想寫,因此隨後作者想讀? – user2930006

+0

@ user2930006:您需要使用2個管道。 – kadina