2012-11-14 37 views
0

我試圖猜測管道中有多少數據,並且我不想使用while(read),因爲它在EOF之前阻塞。管道中有多少數據(C++)

有沒有辦法做到這一點?

我真正的我想是這樣的:

i = pipe1.size(); 
pipe1.read(i); 

我再說一遍,我不希望使用while (read),因爲它阻止,直到EOF。

+0

好像你可能需要使管道非阻塞,或使用['select'](http://linux.die.net/man/3/select)來知道它何時有數據要讀取。 –

+0

不完全。我的管道正在獲取數據很長一段時間,我想讀一段時間後在管道中的數據。我也使用fork,並且不能使用線程。 –

+0

這個想法很好,但在我的情況下,數據快速且順序地進入管道。 –

回答

6

來自管道的數據量可能是無限的,就像流,在管道中沒有size的概念。如果你不希望它阻止,如果在調用時pipe2()沒有什麼閱讀您應該設置O_NONBLOCK標誌:

pipe2(pipefd, O_NONBLOCK); 

,當你調用read()如果沒有數據,它會失敗,並設置errnoEWOULDBLOCK

這樣
if (read(fd, ...) < 0) { 
    if (errno == EWOULDBLOCK) { 
     //no data 
    } 
    //other errors 
} 

從手冊頁:

O_NONBLOCK:設置O_NONBLOCK文件狀態標誌上的兩個新打開 文件說明。使用此標誌可以節省對fcntl(2)至 的額外調用,以達到相同的結果。

您還可以在阻塞管道上使用select()超時。

+0

不完全。我的管道長時間獲取數據,我想在用戶請求時讀取管道中的數據。我也使用fork,並且不能使用線程。 –

+0

@HamedJML您可以隨時從管道中讀取數據。如果管道中沒有任何東西,你會得到'EWOULDBLOCK'錯誤,並且可以返回去做別的事情。在寫入管道時應該小心,因爲它有一種小緩衝區,當緩衝區滿時,寫入程序會阻塞。 –

+0

這個想法很好,但在我的情況下,數據快速且順序地進入管道。 –

1

這可以幫助你,但它是針對UNIX的:

#include <iostream> 

#include <sys/types.h> 
#include <sys/ioctl.h> 
#include <sys/socket.h> 
#include <errno.h> 

int pipe_fd; /* your pipe's file descriptor */ 

...... 

int nbytes = 0; 

//see how much data is waiting in buffer 
if (ioctl(pipe_fd, FIONREAD, &nbytes) < 0) 
{ 
    std::cout << "error occured: " << errno; 
} 
else 
{ 
    std::cout << nbytes << " bytes waiting in buffer"; 
}