0

この質問が繰り返されると言って、人々はこの質問に苦労するだろうと確信しています。しかし、私は具体的なことを尋ねるつもりでした。選択呼び出しがハンドルを取得できず、ポーリング システム呼び出しがハンドルを認識できるというシナリオに直面しました。

その背後になだめるような理由は見つかりません。シナリオを説明しましょう-同じマシンにないサーバーにscocketクライアントを登録しようとしていました。クライアントが同じマシンにある場合、select システム コールは効率的に機能します。ただし、同じマシンの一部ではない場合、失敗し、ポーリングが機能します。

この背後にある一般的な反響はありますか?(注:私は ACE ラッパー ライブラリを使用しています) 追加されたコード スニペット

           int noOfHandles = 4;
            int handles[4];

            int result = thedserver->get_handles(handles,noOfHandles);

            if ((result < 0 ) || (noOfHandles <= 0))
            {
                    return -1;
            }
            ACE_Handle_Set dsdHandleSet;

            for( int i = 0 ;  i < noOfHandles ; i++)
            {
                    cout << "handles: " << handles[i] << endl;
                    dsdHandleSet.set_bit(handles[i]);
            }
            cout << "noOfHandles: " << noOfHandles << endl;
            ACE_Time_Value tv1(60, 0);

            while(1)
            {
                    int res = ACE::select(dsdHandleSet.max_set() + 1, &dsdHandleSet, 0, 0,&tv1);
                    cout << "res: " << res << endl;
            } 
4

3 に答える 3

2

あなたのコードが何をしようとしているのかよくわかりません。なぜselect関数を使うのかわかりませんがwhile(1)、ここにはいくつかの問題があります。select()の男性を必ず読んでください

まず、タイムアウトを設定します。ハンドルの準備ができるまで永久に待機する場合はNULL、タイムアウト値を渡します。

次に、実行するたびselect()にタイムアウトを変更するため、使用する場合は書き直す必要があります。pselect()これを回避するために使用できます。

最後に、selectを呼び出す前に、とを使用FD_ZERO()してファイル記述子をクリアおよび設定する必要があります。FD_SET()

これのいくつかはACEライブラリで抽象化されている可能性があります。私はそれをよく知らないのですが、一般的に、これらは間違っている/欠落していると私が思う部分です。

于 2012-11-01T11:51:03.283 に答える
1

ACE ライブラリについてはわかりませんが、selectシステム コールがその引数を変更します。selectループ内でを呼び出すたびに、セットを再作成する必要があります。

于 2012-11-01T11:42:59.067 に答える
1

コードにエラーがあるか、ファイル記述子が FD_SETSIZE の範囲外にあると思われます (これはコードのエラーです)。select/poll がどのように実装されているかを調べたシステムでは、select は、カーネル内部で引数を同等の poll 呼び出しに変換することによって実装されます (古いシステムではその逆)。言い換えれば、機能的な違いはないはずです。

于 2012-11-01T11:34:41.933 に答える