select时间问题
FD_SET(srvSock,&usFds);
tv.tv_sec = 1;
tv.tv_usec = 0;
int index = 0;
while(1)
{
n = select(maxSock + 1, &usFds, NULL, NULL, &tv);
if(FD_ISSET(srvSock,&usFds))
{
cout<<"test:"<<srvSock<<endl;
}
cout<<"no cli:"<<n<<" time:"<<index++<<" errno:"<<errno<<endl;
}
为什么这个代码第一次等的时候正常,后续会狂打第二个cout,时间根本就不够1秒就开始打了。
过程中没有任何客户端连接,LINUX
谢谢
------解决方案--------------------FD_SET(srvSock,&usFds);
int index = 0;
while(1)
{
gettimeofday(&tv, NULL);
tv.tv_sec += 1;
tv.tv_usec += 0;
n = select(maxSock + 1, &usFds, NULL, NULL, &tv);
if(FD_ISSET(srvSock,&usFds))
{
cout<<"test:"<<srvSock<<endl;
}
cout<<"no cli:"<<n<<" time:"<<index++<<" errno:"<<errno<<endl;
}
linux下
------解决方案--------------------较新的版本中,select中的struct timeval *timeout变量会改变
select返回时,timeout变量会变为还剩多长时间没睡眠。
所以原因也就很清楚了。
把tv.tv_sec = 1;
tv.tv_usec = 0;
放到while(1)里面。
结帖拿分
------解决方案--------------------ubuntu 12.04 LTS 中的man select的解释:
On Linux, select() modifies timeout to reflect the amount of time not
slept; most other implementations do not do this. (POSIX.1-2001 per‐
mits either behavior.) This causes problems both when Linux code which
reads timeout is ported to other operating systems, and when code is
ported to Linux that reuses a struct timeval for multiple select()s in
a loop without reinitializing it. Consider timeout to be undefined
after select() returns.
------解决方案--------------------1楼的,timeout里面是相对时间,,不是绝对时间。。
应该去掉gettimeofday(&tv, NULL); 还有set也得每次赋值。
因为每次select返回时,fd_set参数里面会变为相应事件发生的,
如果这段时间没数据读 , 则select返回时rset会为空 ... . . . OK
fd_set usFds , rset;
...
FD_SET(srvSock,&usFds);
tv.tv_sec = 1;
tv.tv_usec = 0;
int index = 0;
while(1)
{
tv.tv_sec = 1;
tv.tv_usec = 0;
rset = usFds;
n = select(maxSock + 1, &usFds, NULL, NULL, &tv);
if(FD_ISSET(srvSock,&usFds))
{
cout<<"test:"<<srvSock<<endl;
}
cout<<"no cli:"<<n<<" time:"<<index++<<" errno:"<<errno<<endl;
}