选择非阻塞读取

时间:2015-03-04 10:08:21

标签: linux sockets select nonblocking

我很难在网上找到答案。

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

我发现选择手册页没有发现它是微不足道的:

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确实会阻止,那么它的返回值应该是多少?读取套接字不会阻塞,但套接字没有可供读取的数据..

当我回到家时,我会写一些代码示例并编辑这个问题,这可以帮助其他人搜索这个主题。

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

下面是一个小 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] = '\0';
            printf("read: %s\n", buf);
        } else {
            printf("got an error\n");
        }
    }
}

答案 2 :(得分:-1)

如果您使用read()而没有非阻止,程序将阻止阻止您的代码流。但是如果你使用非块模式,select()将立即返回而不会阻塞代码流,只有在有一些数据需要读取时才返回大于零的值。