C语言 读取描述符的非阻塞调用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5616092/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Non-blocking call for reading descriptor
提问by HelloWorld
I have a fd descriptor, which I can use to read from by calling read(fd, buffer,...). Now, I want to check if there is anything to read before actually making the call, because the call is blocking. How do I do this?
我有一个 fd 描述符,我可以通过调用read(fd, buffer,...). 现在,我想在实际拨打电话之前检查是否有任何要阅读的内容,因为电话正在阻塞。我该怎么做呢?
回答by Judge Maygarden
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
The code snippet above will configure such a descriptor for non-blocking access. If data is not available when you call read, then the system call will fail with a return value of -1 and errno is set to EAGAIN. See the fnctlman pages for more information.
上面的代码片段将为非阻塞访问配置这样一个描述符。如果调用 read 时数据不可用,则系统调用将失败并返回 -1 并且 errno 设置为 EAGAIN。有关更多信息,请参阅fnctl手册页。
Alternatively, you can use selectwith a configurable timeout to check and/or wait a specified time interval for more data. This method is probably what you want and can be much more efficient.
或者,您可以使用带有可配置超时的select来检查和/或等待指定的时间间隔以获取更多数据。这种方法可能是您想要的,并且效率更高。
回答by R.. GitHub STOP HELPING ICE
Use selector pollto query whether the file descriptor has data available for read:
使用select或poll查询文件描述符是否有可供读取的数据:
fd_set fds;
FD_ZERO(&fds);
FD_SET(&fds, fd);
if (select(fd+1, &fds, 0, 0)==1) /* there is data available */
回答by Ken Rockot
Ok, STDINcan be read in non-blocking mode as you would like. You will first need to set the socket to non-blocking mode, as in
好的,STDIN可以根据需要以非阻塞模式读取。您首先需要将套接字设置为非阻塞模式,如
int flags = fcntl(fd, F_GETFL, 0);
if(fcntl(fd, F_SETFL, flags | O_NONBLOCK))
;// some kind of fail
When you're ready to read data from the buffer, you can attempt a read as follows:
当您准备好从缓冲区读取数据时,您可以尝试如下读取:
int count;
char buffer[1024];
count = read(fd, buffer, 1024);
if(count < 0 && errno == EAGAIN) {
// If this condition passes, there is no data to be read
}
else if(count >= 0) {
// Otherwise, you're good to go and buffer should contain "count" bytes.
}
else {
// Some other error occurred during read.
}
Note that of course the buffer size of 1024is arbitrary.
请注意,当然缓冲区大小1024是任意的。
回答by Elalfer
I think you should use selector pollfunctions to check if there are something to read from the descriptor.
我认为您应该使用select或poll函数来检查是否有要从描述符中读取的内容。
回答by Ankur Soni
use poll for timeout:
struct pollfd p;
int n;
while ((n = poll(&p, 1, iTo)) < 0)
{
if (errno == EAGAIN || errno == EINTR)
continue;
}
if (!n) {
errno = ETIMEDOUT;
}
while ((len = read(Fd, anyBuff, sizeof(anyenter code hereBuff))) < 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
}
回答by mu is too short
回答by Novin Shahroudi
Check out the API or system/tool you are using for your specific programming purpose. (descriptors/file descriptors have many uses in Linux programming such as socket programming, file manipulation, shared_memory, etc.)
查看您用于特定编程目的的 API 或系统/工具。(描述符/文件描述符在 Linux 编程中有很多用途,例如套接字编程、文件操作、shared_memory 等)
For example one time I used inotify (for monitoring file system events). This API gives you ability to create non-blocking file from the first point and there's no need to use fcntl or such APIs to modify the created file descriptor.
例如,有一次我使用了 inotify(用于监视文件系统事件)。此 API 使您能够从一开始就创建非阻塞文件,并且无需使用 fcntl 或此类 API 来修改创建的文件描述符。
Probably other tools or API's that you're going to use have such functionality and you can set such option in their initiation or such steps (check this first).
您将要使用的其他工具或 API 可能具有此类功能,您可以在其启动或此类步骤中设置此类选项(请先检查)。
But generally yes using fcntl is the answer and it might be interesting to know that inotify itself uses fcntl itself too. (refer to the manual pages of Linux)
但通常使用 fcntl 是答案,知道 inotify 本身也使用 fcntl 可能会很有趣。(请参阅 Linux 的手册页)
select() can give you a same functionality as it operates on file descriptors for monitoring events with a specified limited time but keep in mind that the main usage of select is for monitoring multiplefile descriptors.
select() 可以为您提供与文件描述符相同的功能,用于在指定的有限时间内监视事件,但请记住,select 的主要用途是监视多个文件描述符。

