Select 非阻塞读取

Select with non-blocking reads

我很难在网上找到这个问题的答案。

在 Linux 上调用 select 读取文件并且套接字设置为非阻塞时应该发生什么 ?

我不认为它是微不足道的,因为 select 手册页指出:

Those listed in readfds will be watched to see if characters become available for reading (more precisely, to see if a read will not block; in particular, a file descriptor is also ready on end-of-file)

如果套接字设置为非阻塞,它应该永远不会阻塞,select return 应该立即阻塞吗?这听起来不对……海德文档是错误的还是忽略这种情况?

此外,如果 select 确实会阻塞,那么它的 return 值应该是多少?读取套接字不会阻塞,但套接字没有可读数据..

当我回到家后,我会写一些代码示例并编辑这个问题,这对谷歌搜索这个主题的其他人有很大帮助。

如果你select()读取一个没有数据等待读取的套接字(也没有任何错误),它将阻塞(直到select()超时)。

如果您使用 read() 而不使用非阻塞,程序将阻塞,从而阻塞您的代码流。但是,如果您使用非阻塞模式,select() 将立即 return 而不会阻塞代码流 return 仅当有一些数据要读取时才使用大于零的值。

这是一个小 C 程序,显示在非阻塞文件描述符上调用 select(2) 仍然会阻塞,直到有内容可读:

#include <stddef.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/select.h>
#include <unistd.h>
#include <fcntl.h>

int main(int argc, char **argv) {
    int ready;
    struct timeval *pto;
    fd_set readfds, writefds;
    char buf[1024];
    int bytes;
    int fd = 0; // stdin

    pto = NULL;
    FD_ZERO(&readfds);
    FD_ZERO(&writefds);
    FD_SET(fd, &readfds);

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

    while (1) { 
        ready = select(1, &readfds, &writefds, NULL, pto);

        if (ready == -1) {
            printf("got -1\n");
            return 1;
        }

        printf("ready = %d\n", ready);

        bytes = read(fd, buf, 1024);
        if (bytes == 0) {
            printf("all done\n");
            return 0;
        } else if (bytes > 0) {
            buf[bytes] = '[=10=]';
            printf("read: %s\n", buf);
        } else {
            printf("got an error\n");
        }
    }
}