2011-11-15 129 views
3

以下代碼通過管道讀取來自其他進程的消息。所有進程都能正確打印出所有的消息,但是它們將永遠不會經過while循環。嘗試在Eclipse中進行調試,讀完所有消息後,它將停止在while循環中。進程掛起讀取

索引是分配給每個進程的編號。第一個進程的索引== 0. 消息本身就是發送消息的進程的索引。

while((n = read(fd[index][0], &mymsg, sizeof(int))) == sizeof(int)) 
     printf("process%d has received a message from process%d\n", index, mymsg); 

任何想法爲什麼會發生這種情況?

下面是每個過程是如何寫入另一個:

// Write to other process 
if(write(fd[index2][1], &index, sizeof(int)) != sizeof(int)) 
    sys_error(2); 

這樣做五次。 fd是每個進程的讀寫結束表。

+0

目前尚不清楚爲什麼這不是你期望的行爲。代碼應該在什麼情況下通過while循環? –

+0

@DavidSchwartz如果它讀入沒有字節或返回錯誤。 – sj755

+0

你有什麼特別的理由可以期待這些事情發生嗎?如果不是,那麼爲什麼它應該退出while循環? (文件描述符是否非阻塞?) –

回答

5

read()的呼叫被阻止,直到出現更多數據。從man page for pipe

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

後您輸入while循環這樣做是爲了每一個前打開每個文件描述:

fcntl(fd, F_SETFL, O_NONBLOCK); 

但是,你真的應該阻斷閱讀了與非阻塞I/O,包括閱讀管道的手冊頁,閱讀,fcntl等

+0

我可以有一些示例代碼?我對這個功能不太熟悉。 – sj755

+0

@ seljuq70:您是否嘗試過fctntl手冊頁?我剛剛在Google中輸入了'fcntl F_SETFL O_NONBLOCK',並獲得了一些帶有示例代碼的點擊。無論如何,我編輯我的答案以添加更多信息。 – kbyrd

+0

我在讀之前試過這個:fcntl(fd [index] [0],F_SETFL,O_NONBLOCK);由於某些原因,進程0不再打印任何東西? – sj755