2016-12-11 191 views
0

我使用FIFO使兩個進程進行通信。
讀FIFO:爲什麼會阻塞然後非阻塞

//client: 
const char * msg = "Hello, I'm cleint1."; 
const char * fifoName = "../server/fifo.tmp"; 
int fd = open(fifoName, O_WRONLY); 
write(fd, msg, strlen(msg) + 1); 
close(fd); 



//server: 
char msg[100]; 
const char * fifoName = "fifo.tmp"; 
mkfifo(fifoName, 0666); 
int fd = open(fifoName, O_RDONLY); 
while(read(fd, msg, 100) > 0) 
{ 
    std::cout<<"msg received: "<<msg<<std::endl; 
} 
close(fd); 
unlink(fifoName); 


服務器將首先阻塞在那裏等待一些消息在fifoName。當一些消息到達時(客戶端執行),服務器讀取它們,然後循環結束。

我現在很困惑。因爲我不知道爲什麼服務器第一次調用read並且它在那裏阻塞,而當它再次調用read並且它不再阻塞時。

我打印的read返回值和我收到的第一條消息後,得到0。

我需要的是使read每次都被阻塞,以便服務器可以在某個客戶端發送消息後立即收到任何消息。

+0

應打印字符串錯誤(錯誤),看看是什麼錯誤。 –

+0

@SumitGemini,我打印'read'的回報,我得到0. – Yves

+0

所以你想讓你的服務器無限運行?連續閱讀? –

回答

0

你可以簡單地重試讀取。例如

int iResult; 

do 
{ 
    iResult = read(fd, buffer, size); 
    if (0 == iResult) 
    { 
      // Skip to the end of the do loop 
      continue; 
    } 
     // Handle real errors 
} while (!condition); 
1

你有0作爲指示劑有左沒有更多的數據並且將有沒有更多的數據作爲管的另一側得到關閉。

我認爲您希望服務器堅持並處理多個客戶端,甚至可能同時處理多個客戶端。

管道是根本不適合這個目的。您想用unix插座代替。

最後,循環像這樣的:

while(read(fd, msg, 100) > 0) 
{ 
    std::cout<<"msg received: "<<msg<<std::endl; 
} 

是根本錯誤的。由於信號到達,讀取錯誤非常容易。

另請注意,違反DRY的方法是重複緩衝區大小的'100'而不是例如。使用sizeof(msg)。