读书人

select立刻返回0,errno=0根本没有等

发布时间: 2012-02-05 12:07:14 作者: rapoo

select立刻返回0,errno=0,根本没有等到超时的情况,为何
...
tv.tv_sec = timeout;

for( ;; )
{
FD_ZERO( &readmask );
FD_SET( sockfd, &readmask );

switch( select( sockfd + 1, &readmask, NULL, NULL, &tv ) )
{
case 0:
return TIMEOUT;
case -1:
if ( errno == EINTR )
continue;
return BROKEN;
default:
if ( FD_ISSET( sockfd, &readmask ) )
{
...
}
}
}
...

奇怪的是,明明timeout> 0,但是select立刻返回0,实际上客户端发送报文是成功的,而服务端却收不到数据(TIMEOUT)。

sockfd是子进程通过recvmsg从父进程接收过来的,父进程那边accept后就用sendmsg发给子进程了,中间没有做其他操作。

本来程序一直正常的,但是最近偶然就会出现这种情况,而且有时几个子进程,有的正常,有的就有这种情况。

各位高手能否指点一下,为什么会出现这种情况?


[解决办法]
tv.tv_sec = timeout;
这条语句要在select之前,循环之内。
[解决办法]
tv.tv_sec = timeout;
这条语句要在select之前,循环之内。
——————————————————————————
这句话没有必要吧,只读的

——————————————————————————

struct timeval
{
time_t tv_sec;
time_t tv_usec;
};
是不是搂主设的是tv_usec太小了阿,有的系统达不到你设的这个精度就会出现你说的问题

[解决办法]
tv.tv_sec = timeout;
这条语句要在select之前,循环之内。
——————————————————————————
这句话没有必要吧,只读的

——————————————————————————

struct timeval
{
time_t tv_sec;
time_t tv_usec;
};
是不是搂主设的是tv_usec太小了阿,有的系统达不到你设的这个精度就会出现你说的问题
-----------
rexp(沧浪客) 说得很好!

man select
...
....
BUGS
Version 2 of the Single UNIX Specification (``SUSv2 ' ') allows systems to
modify the original timeout in place. Thus, it is unwise to assume that
the timeout value will be unmodified by the select() system call.

[解决办法]
tv.tv_sec = timeout;
这条语句要在select之前,循环之内。
——————————————————————————
这句话没有必要吧,只读的

——————————————————————————

完全要这样做,因为tv 会被改写成 rest 时间,大部分情况是 0
[解决办法]
每次select 之前,设置tv.tv_sec这个时间,应该就可以了。
[解决办法]
tv.tv_sec = 5
tv.tv_usec = 0;//add

try it again

读书人网 >UNIXLINUX

热点推荐