2012-11-14 33 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"; 
}