日期:2014-05-16  浏览次数:20681 次

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;
}