unix 用于阅读描述符的非阻塞调用

1cklez4t  于 2022-11-04  发布在  Unix
关注(0)|答案(6)|浏览(163)

我有一个fd描述符,我可以通过调用read(fd, buffer,...)来读取它。现在,我想在实际进行调用之前检查是否有要读取的内容,因为调用被阻塞了。我该怎么做呢?

4szc88ey

4szc88ey1#

int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);

上面的代码片段将为非阻塞访问配置这样一个描述符。如果在调用read时数据不可用,则系统调用将失败,返回值为-1,并且errno设置为EAGAIN。有关更多信息,请参阅fnctl手册页。
或者,您可以使用select和一个可配置的超时来检查和/或等待一个指定的时间间隔以获取更多的数据。

jhdbpxl9

jhdbpxl92#

使用selectpoll查询文件描述符是否有可供读取的数据:

fd_set fds;
FD_ZERO(&fds);
FD_SET(&fds, fd);
if (select(fd+1, &fds, 0, 0)==1) /* there is data available */
a0x5cqrl

a0x5cqrl3#

根据您正在做的事情,您可能能够彻底解决这个问题,并使用select来告诉您文件描述符何时有内容要读取。

42fyovps

42fyovps4#

对超时使用轮询:

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;
}
pxyaymoc

pxyaymoc5#

我认为您应该使用selectpoll函数来检查是否有要从描述符中读取的内容。

osh3o9ms

osh3o9ms6#

检查您正在使用的API或系统/工具以用于特定的编程目的。(描述符/文件描述符在Linux编程中有许多用途,如套接字编程、文件操作、shared_memory等。)
例如,有一次我使用了inotify(用于监控文件系统事件),这个API让你能够从第一个点创建非阻塞文件,并且不需要使用fcntl或类似的API来修改创建的文件描述符。
可能您要使用的其他工具或API也有这样的功能,您可以在它们的初始化或步骤中设置这样的选项(首先选中此选项)。
但通常情况下,使用fcntl是正确的,而且了解inotify本身也使用fcntl本身可能会很有趣。(请参阅Linux手册页)
select()可以为您提供与它在文件描述符上操作相同的功能,用于在指定的有限时间内监视事件,但请记住,select的主要用途是监视多个文件描述符。

相关问题