int main() {
fd_set readfds;
fd_set writefds;
FD_ZERO(&readfds);
FD_ZERO(&writefds);
FD_SET(0, &readfds);
int fd = open("random_path", O_WRONLY);
FD_SET(fd, &writefds);
struct timeval tv;
tv.tv_sec = 10;
tv.tv_usec = 0;
int r = 0;
string s;
int i = 0;
// Running loop 5 times
while (i<5) {
r = select(fd+1, &readfds, &writefds, NULL, &tv);
cout<<"r is "<<r<<endl;
if (r == -1) {
cout<<"error"<<endl;
exit(1);
}
if (FD_ISSET(0, &readfds)) {
cout<<"reading from stdin"<<endl;
cin>>s;
cout<<"s is "<<s<<endl;
}
if (FD_ISSET(fd, &writefds)) {
cout<<"writing to file"<<endl;
write(fd, s.c_str(), s.length());
}
cout<<"sleeping"<<endl;
sleep(5);
i += 1;
}
}
当我运行这个时,我得到的输出是
r is 1
writing to file
sleeping
random text to set stdin fd
r is 1
writing to file
sleeping
如您所见,代码永远不会进入 FD_ISSET(0, &readfds) ,因为它永远不会打印“从 stdin 读取”,但是,如果我将选择系统调用从 select(fd+1) 更改为 select(1 或 2),即小于 fd 的任何内容,然后我可以看到“从 stdin 读取”
qqq
r is 1
reading from stdin
s is qqq
sleeping
必须在每次迭代时设置 fdset。每次调用 select() 时都会修改(销毁)所有 fdset,从而添加 FD_ZERO($readfds); FD_SET(0,&readfds);作为重新初始化的一部分,有效