2017-02-03 12 views
2

ファイル記述子Aから読み込むのを待つ必要があり、ファイル記述子Bが書き込み可能な場合にのみ読み込みます。これは、すぐに条件のいずれかが発生し戻された選択問題があった読み取り可能なファイル記述子と書き込み可能なファイル記述子を待ちます

while (true) { 
    select(A readable, B writeable, timeout) 
    if (A was readable and B was writeable) { 
    ReadFromAWriteToB(); 
    } 
} 

: 私の最初の実装は、この(擬似コード)のようでした。これは問題がありました。なぜなら、Aは可読性が10%であったからですが、Bは書き込み可能であったため、Aから読み取るデータはほとんどなくてもBに書き込みました。

私の次の実装では、このようなものだった:これは良くなった

while (true) { 
    select(A readableB, timeout); 
    if (A was readable) { 
    select(B writeable, 0); // Check if it is writeable right now 
    if (B was writeable) { 
     ReadFromAWriteToB(); 
    } 
    } 
} 

が、私は、Aはすぐに最初の選択を返しますので、読みやすいですが、Bが書き込み可能ではないので、私はになるだろうピークを取得Bが再び書き込み可能になるまでビジー・ループ。

したがって、1ミリ秒など、2番目の選択で小さな待機時間を追加できます。 私が本当にやりたいことは、どちらか一方の条件だけでなく両方の条件が有効になるまでselect/pollですが、select/pollがこれをサポートしているとは思いません。 使用する優れたAPIがあるか、このループを構成するにはより良い方法がありますか?

答えて

2

Bが書込み不可能であることを知った後にスリープ状態を追加することはどうですか?

while (true) { 
    select(A readableB, timeout); 
    if (A was readable) { 
    select(B writeable, 0); // Check if it is writeable right now 
    if (B was writeable) { 
     ReadFromAWriteToB(); 
    } 
    else { 
     sleep for an appropriate amount of time 
    } 
    } 
} 

これは以下となります。Aの準備ができているとBが

  • ではありませんが、我々は常にB
  • を確認する前にAの新鮮なチェックを行うことを確認したときに

    • がタイトなループを防ぎますAの準備ができてから無制限に待つことができたら、ループを次のように書き直すことができます:

      while (true) { 
          select(A readableB, timeout); 
          if (A was readable) { 
          b_timeout = 0 
          while true { 
           select(B writeable, b_timeout); // Check if it is writeable right now 
           if (B was writeable) { 
           ReadFromAWriteToB(); 
           break; 
           } 
           sleep for a small amount of time to prevent tight loop around B 
           b_timeout += a few milli seconds 
          } 
          } 
      } 
      

      これは

      • は、我々はそれが、これは理にかなっている希望

      準備ができて発見した後、Aをチェックする回数を減らし、以前のソリューション

    • のようにタイトなループを防止します。

    +0

    永遠に待つNULLタイムアウトを選択するだけで、2番目の例を簡略化できます。 – pilkch

    +1

    もう一つの選択肢は、スリープを避けるためにselect writeableで短いタイムアウトを使用することです。私は私のプロジェクトでこのオプションを使うつもりだと思う。私と一緒に働いてくれてありがとう! – pilkch

    関連する問題