如何将read()设置为非阻塞模式

3

目前我在调用read()时遇到了一个问题:

unsigned char byData[1024] = {0};
ssize_t len = read(fd, byData, sizeof(byData));

其中fd是文件描述符。

read()是阻塞的,这不是我想要的。有没有简单的方法将read设置为非阻塞或超时?该代码与inotify一起使用。

感谢任何帮助。


1
请参见http://cr.yp.to/unix/nonblock.html(简而言之:像下面的答案一样更改fd,而不是read())。 - loreb
可能是读取描述符的非阻塞调用的重复问题。 - Ben Stern
4个回答

5
您不能将这些系统调用设为非阻塞的;相反,您可以将它们所在的文件描述符设为非阻塞。
fcntl(fd, F_SETFL, O_NONBLOCK) 

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

如果你需要添加 O_NONBLOCK 并且保留之前设置的标志。

这种方式 read 将不会阻塞。如果你想设置超时,使用 selectpoll

fd_set fds; 
FD_ZERO(&fds);
FD_SET(fd, &fds);

struct timeval t = {/*seconds*/, /*microseconds*/};
select(fd + 1, &fds, NULL, NULL, &t);

错误处理和后续工作(select将覆盖fdst)由您负责。

3

您可以使用 poll 函数来监控文件描述符,以便知道何时有数据可供读取。然后再调用 read() 函数。

# Poll definition
int poll(struct pollfd *fds, nfds_t nfds, int timeout);

正如您所看到的,您可以设置超时时间。这在文件无法使用O_NONBLOCK标志打开或根本没有调用open()的情况下非常有用。


2

使用带有O_NONBLOCK标志的open(fd, ...)进行调用。

来自open()手册页:

O_NONBLOCK或O_NDELAY:在可能的情况下,以非阻塞方式打开文件。返回的文件描述符上的任何后续操作都不会导致调用进程等待。关于FIFO(命名管道)的处理,请参见fifo(7)。有关O_NONBLOCK与强制文件锁和文件租约结合使用时的影响的讨论,请参见fcntl(2)。


很不幸,我正在使用的代码没有调用open。这是代码: s_MyRes.wd = inotify_add_watch(s_MyRes.fd, ctx.szFolder.c_str(), ctx.uMask); 在此之后,会调用read(),它是阻塞的。 - Smithy

0

这个主题已经在这里描述过了。

另外,你可以尝试使用计时器或线程。 这是线程的示例:

#include <pthread.h>

unsigned char byData[1024] = {0};
ssize_t len;

void *thread(arguments) {
  while (1) {
    len = read(fd, byData, sizeof(byData));
  }

int main(){
  pthread_t pth;
  pthread_create(&pth, NULL, thread, arguments);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接