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");
}
}
}
我很难在网上找到这个问题的答案。
在 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");
}
}
}