为了更清楚地解释我想做什么,我希望我的代码每隔 2.5 秒(假设)检查用户是否输入了某些内容(或者 0 以外的另一个文件描述符是否有数据要读取),直到程序停止。
如果用户输入了某些内容,一个简单的printf()
将通知他,然后程序将再次检查用户是否在接下来的 2,5 秒内输入了某些内容。
否则,它应该简单地打印时间用完,然后在接下来的 2,5 秒内再次检查用户输入。
这是我从Beej的网络编程指南中窃取的代码片段,并进行了修改以(尝试)满足我的要求:
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#define STDIN 0 // file descriptor for standard input
int main(void){
struct timeval tv;
fd_set readfds;
FD_ZERO(&readfds);
FD_SET(STDIN, &readfds);
tv.tv_sec = 2;
tv.tv_usec = 500000;
while(1){
select(STDIN+1, &readfds, NULL, NULL, &tv);
if (FD_ISSET(STDIN, &readfds)){
printf("A key was pressed!n");
tv.tv_sec = 2;
tv.tv_usec = 500000;
}else{
printf("Timed out.n");
tv.tv_sec = 2;
tv.tv_usec = 500000;
}
}
return 0;
}
只要我不按任何键,就可以正常工作,每 2,5 秒打印一次"超时"。但是如果我输入一些东西,它似乎忽略了用户输入并继续打印"超时"。
另一方面,如果我在无限循环中声明fd_set
和struct timeval
,一旦我输入某些内容,就会无限打印一个键被按下,就好像它忽略了超时一样。
我不知道为什么这么简单的代码不起作用。我想我错过了一些我不知道的文件描述符。
每次返回select
时都应该重置 -> FD_ZERO(&readfds)
readfds
并添加文件描述器 -> FD_SET(STDIN, &readfds)
,因为超时时文件描述符将从集合中删除
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#define STDIN 0 // file descriptor for standard input
int main(void){
struct timeval tv;
fd_set readfds;
while (1) {
int count; /* how many descriptors are contained in the set. */
FD_ZERO(&readfds);
FD_SET(STDIN, &readfds);
tv.tv_sec = 2;
tv.tv_usec = 500000;
count = select(STDIN + 1, &readfds, NULL, NULL, &tv);
if ((count > 0) && (FD_ISSET(STDIN, &readfds) != 0)) {
printf("A key was pressed!n");
} else if (count == -1)
/* check for the error here */
} else {
printf("Timed out.n");
}
}
return 0;
}
如您所见,您还应该检查 select
的返回值,以检查错误,以防出现错误,然后检查errno
以查看发生了什么,然后检查您感兴趣的文件描述符包含在readfds
中。