0

単一の選択呼び出しで最初の非同期サーバーを作成するときに、この問題に遭遇しました。

if( (retv = select((hsock<highestsocket?highestsocket:hsock)+1, &rFdx, &wFdx, &eFdx, 0) ) > 0)
{
   printf("select() ended...\n");
    if(FD_ISSET(hsock, &rFdx))
    {
      // .... handle new connection
    }

    for(unsigned int i=0; i < ClientList.size(); i++)
    {
      ServerClient* client = ClientList[i];

      if(FD_ISSET(client->socket, &rFdx))
      {
        // handle client read
      }
      if(FD_ISSET(client->socket, &wFdx))
      {
           // handle client write
      }    

    }
}

他のスレッドからFD_SETを呼び出すときに、待機を停止してからクライアント書き込みを処理することを選択することを期待しています。

同じスレッドからクライアントソケットでFD_SETを呼び出すと、すべてが期待どおりに機能します。ただし、他のスレッドから呼び出しても何も起こりません。selectは、クライアントからデータを受信するまで待機し続けます。

4

1 に答える 1

2

もちろん、1つのスレッドでデータを変更して、適切な同期がないと変更が他のスレッドで表示されることを期待することはできません。呼び出されるとすぐにselect読み取り、その後は二度と表示されない可能性があります。fd_setただし、selectすでに呼び出されている場合は、必要な同期を取得する方法はありません。あなたは本当にあなたのデザインを再考する必要があります。1つの解決策は、「セルフパイプ」トリックです。select常に入力を探しているパイプを開き、他のスレッドにパイプを介してメッセージを送信させて、保留中のメッセージをキャンセルしselectselectスレッドにファイル記述子のテーブルを再スキャンさせます。 (適切な同期で!)調べて、独自fd_setのを更新する必要があります。

于 2012-09-04T17:50:27.440 に答える