2016-08-24 4 views
-1

ソケットセレクトで-1を返しています。しかし、これは、sybaseデータベースの新規インストールを使用している場合にのみ発生します。このコードを古いデータベースで使用すると、ソケット選択エラーが発生せず、すべて正常に動作します。 65,000を超える、例えば以下how_many = 2、及びそれがfile_limits.rlim_curに動作するとき、次のコードで新しいデータベースfile_limits.rlim_curとが256であることに留意することがtimeout_secs = 60C Solarisでソケット選択エラーが発生しました

重要で

=とソケットselectは-1を返します。私は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

あなたの 'for'ループはどこかにかっこを入れていると思いますか? – yano

+1

'select'が-1を返す場合、' perror'を呼び出して失敗した理由を調べるべきです。 – dbush

+0

おそらくあなたは 'FD_SETSIZE'を行ったでしょうか? http://stackoverflow.com/questions/7976388/increasing-limit-of-fd-setsize-and-select –

答えて

0

本物のヘルプを得るには、実際にはpost an MCVEが必要です。そして、これは実際の答えではなく、より情報に基づいた推測です。

まず、あなたが開いているファイルディスクリプタのint配列を指すint *を通過したばかりしていると仮定すると、これは無意味です:

/* 
** Determine the current limits. 
*/ 

if (getrlimit(RLIMIT_NOFILE, &file_limits) != 0) 
    return(-1); 

あなたはすでに開いファイルディスクリプタを渡さ取得している場合、オープンディスクリプタの数に対するリソース制限はまったく関係がありません。ディスクリプタは既に開いており、何かがにある場合は、に制限があり、一部のディスクリプタでは動作しない可能性があります。

第2に、開いているファイルの制限がFD_SETSIZEの値より大きい場合は、この問題が発生します。あなたが選択するために渡す配列 - - read_fdsexcept_fdsそれぞれが高々FD_SETSIZEの要素があります。

select_fd = select(file_limits.rlim_cur, 
        &read_fds, 
        NULL, 
        &except_fds, 
        &timeout); 

を私はFD_SETSIZEは、Solarisのインストールの上にあるか知っているが、あなたは「それはfile_limits.rlim_curに動作する場合、以下のコードを投稿与えられていません「256です」という質問には、私はそれが起こっていることを強く疑う。 nfds引数が0より小さいか大きい

...

EINVAL:場合Solaris select(3C) man pageの内容を考えると

エラー

select()pselect()機能が失敗しますされていますFD_SETSIZEより。

コードを修正する必要があります。

そして、これは、後に、アレイ内の記述子の飢餓につながる:

for (i = 0; i < how_many; i++) 
    if ((fd[i] >= 0) && 
     (FD_ISSET(fd[i], &read_fds))) 
     return(fd[i]); 

あなたはいつもあなたが見つける活動との最初の記述子を返します。アレイの最初のものが常にビジー状態の場合は、サービスされるのは唯一のものです。

また、except_fdsも無視しています。他の記述子が読み込み可能なデータを持たないような方法で "悪い"コードがある場合、コードはループ以外の処理を停止しますselect()

+0

ありがとうございます。nfds引数を変更すると問題が解決しました。申し訳ありませんが、MCVEを投稿していません。私は今までに見たことのない20年前のコードを修正しようとしており、それをどうやって行うのか分からなかった。 –

関連する問題