我在套接字选择上得到-1的返回值。但是,只有在我们使用新安装的sybase数据库时才会发生这种情况。将此代码与旧数据库一起使用,我没有得到任何套接字选择错误,一切正常。
在下面的示例中,how_many = 2,timeout_secs = 60。
重要的是要注意,在下面的代码中,当它工作时,file_limits.rlim_cur是256.但是新数据库file_limits.rlim_cur =超过65,000并且套接字选择返回-1。我已经尝试将select中的第一个参数硬编码为256,但它仍然返回-1。
int socket_activity( int how_many, int *fd, int timeout_secs )
{
int i;
int select_fd;
fd_set read_fds;
fd_set except_fds;
struct timeval timeout;
struct rlimit file_limits;
/*
** Determine the current limits.
*/
if ( getrlimit( RLIMIT_NOFILE, &file_limits ) != 0 )
return( -1 );
/*
** Set up the select structures. Initialize the timeout to the specified
** seconds. Only non-negative file descriptors are initialized.
*/
FD_ZERO( &read_fds );
FD_ZERO( &except_fds );
for ( i = 0; i < how_many; i++ )
if ( fd[i] >= 0 ) {
FD_SET( fd[i], &read_fds );
FD_SET( fd[i], &except_fds );
} /* of if */
timeout.tv_sec = timeout_secs;
timeout.tv_usec = 0;
/*
** Perform the select and check on the results.
*/
select_fd = select( file_limits.rlim_cur,
&read_fds,
NULL,
&except_fds,
&timeout );
if ( select_fd > 0 ) {
/*
** Scan the list of file descriptors and return which file
** descripitor show activity. Only check non-negative file descriptors.
*/
for ( i = 0; i < how_many; i++ )
if ( ( fd[i] >= 0 ) &&
( FD_ISSET( fd[i], &read_fds ) ) )
return( fd[i] );
/*
** No file descriptor showed activity so return zero to indicate
** that a timeout occured.
*/
return( 0 );
} /* of if */
else
/*
** Simply return the return value from select (the function will
** return a 0 on timeout or a -1 on error).
*/
return( select_fd );
} /* of function */
答案 0 :(得分:0)
你真的需要post an MCVE来获得真正的帮助。由于这一点,这是更明智的推测而不是实际的答案。
首先,假设您已经通过指向int *
打开文件描述符数组的int
,这是没用的:
/*
** Determine the current limits.
*/
if ( getrlimit( RLIMIT_NOFILE, &file_limits ) != 0 )
return( -1 );
如果您已经通过已经打开的文件描述符,那么打开描述符数量的资源限制是完全无关紧要的 - 描述符已经打开,如果某些内容是降低限制,你可能无法对某些描述符采取行动。
其次,如果打开文件的限制大于FD_SETSIZE
中的值,则会出现问题。您传递给选择的数组 - read_fds
和except_fds
- 每个都包含最多FD_SETSIZE
个元素:
select_fd = select( file_limits.rlim_cur,
&read_fds,
NULL,
&except_fds,
&timeout );
我不知道Solaris安装中的FD_SETSIZE
是什么,但是如果您发布了以下代码,那么下面的代码file_limits.rlim_cur
是256
&#34 ;在这个问题上,我强烈怀疑这是怎么回事。鉴于Solaris select(3C)
man page的内容是
<强>错误强>
如果出现
select()
和pselect()
函数将失败:...
EINVAL
nfds
参数小于0
或大于FD_SETSIZE
。
您需要修复代码。
这将导致数组中稍后描述符的饥饿:
for ( i = 0; i < how_many; i++ )
if ( ( fd[i] >= 0 ) &&
( FD_ISSET( fd[i], &read_fds ) ) )
return( fd[i] );
您始终返回包含您找到的活动的第一个描述符。如果数组中的第一个总是忙,那么它就是唯一一个得到服务的人。
你也忽略了except_fds
。如果一个人变坏了#34;在这种情况下,没有其他描述符将具有可读数据,您的代码将停止执行除select()
中的循环之外的任何操作。