我使用选择进行同步I / O多路复用。它将检查任何数据1秒。如果没有数据,1秒后它将显示输出(puts("Waited for 1 sec no data");
)然后它将再次检查数据。但这只是在第一次工作然后它进入无限循环。
有没有替代解决方案。
//..............................
//.............................
//Creating listener socket and other sort of things
struct timeval tv;
tv.tv_sec=1;
tv.tv_usec=0;
while(1)
{
FD_ZERO(master);
FD_SET(listener,master);
fdmax = listener;
int retval=select(fdmax+1,master, NULL, NULL,&tv);
printf("retval is %d\n",retval);
if(retval == -1)
{
perror("Server-select() error");
}else if(retval)
{
puts("Data available");
//If there is no data do some work and checkagain.
}else
{
puts("Waited for 1 sec no data");
//If there is no data do some work and checkagain.
}
}
答案 0 :(得分:2)
来自man select:
在Linux上,select()修改超时以反映未睡眠的时间;大多数其他实现不会这样做。 (POSIX.1-2001允许任何一种行为。)当读取超时的Linux代码移植到其他操作系统时,以及当代码移植到Linux时,在循环中为多个select()s重用struct timeval时,这会导致问题重新初始化它。在select()返回后,请考虑超时未定义。
与master
一样,您必须在每次tv
来电之前设置select
。
在我的代码中,我经常有类似的东西:
FD_ZERO(master);
FD_SET(listener,master);
fdmax = listener;
while (1)
{
struct timeval tv = {1, 0};
int retval=select(fdmax+1,master, NULL, NULL,&tv);
printf("retval is %d\n",retval);
if(retval == -1) {
perror("Server-select() error");
break; // <-- notice the break here
} else if(retval) {
puts("Data available");
} else {
puts("Waited for 1 sec no data");
}
}
答案 1 :(得分:0)
除了Mathieu答案外,似乎在每次调用FD_ZERO之前都必须先将其调用为空的可读文件句柄集,然后再调用FD_SET。
我一直在努力选择()在到达超时后始终返回0的事实,无论是否有要读取的数据(我从键盘上读取输入,我用'cat'命令检查了每次按键时都发送数据)
代码应为(记入先前答案):
while (1)
{
struct timeval tv = {1, 0};
FD_ZERO(master);
FD_SET(listener,master);
fdmax = listener;
int retval=select(fdmax+1,master, NULL, NULL,&tv);
printf("retval is %d\n",retval);
if(retval == -1) {
perror("Server-select() error");
break; // <-- notice the break here
} else if(retval) {
puts("Data available");
} else {
puts("Waited for 1 sec no data");
}
}