1

読み取り元の接続が開いているselectループがあり、各接続にステートマシンが接続されていて、ネットワークを介してやってくるものを解析して正しいことを行うと仮定します。したがって、接続の1つであるcが準備ができていて、selectループがそれをステートマシンに渡してm処理するとします。接続から10バイトを読み取りたいので、を使用しますreadpartial。残念ながら、6バイトしか取得されていないため、m6バイトを読み取ってブロックを解除します。次回ループが私たちに渡すとき、cそれはさらに11バイトあります。mは、前回selectループから渡されたときの状態のままであり、cさらに4バイトを読み取る必要があることを認識しているため、これらの4バイトを次のように読み取ります。readpartial(4)は、現在バッファにあり、新しい状態に移行する10バイトを使用して、ある種の副作用操作を実行します。mまだ接続を保持しているので、この時点でループのブロックを解除するか、新しい状態が指示する操作の実行を開始できます。これらの操作の1つは、を含むものである可能性がありますreadpartial。この場合、正しいことは、readpartialブロックされないため、接続の処理を続行することです。しかし、アクションのシーケンスが次のようになっていると仮定します。6バイトを受信し、6バイトを読み取り、ブロックを解除し、4バイトを受信し、4バイトを読み取り、いくつかの処理を実行します。その場合、読むべきものは何も残っていないので、ステートマシンが呼び出すことを決定した場合readpartial接続では、選択ループがブロックされますが、これは望ましくない状況です。この場合の正しいことは、ステートマシンがブロックを解除し、選択ループが再び発生するのを待つことです。

選択ループをブロックしたくない場合や、接続バッファーにバイトを残したくない場合に、この問題を解決するための正確で効率的な方法は何ですか?RubyのSocketとIOAPIを調べましたが、読むべきものがあるかどうかを教えてくれるメソッドが見つかりません。read_nonblockは、1バイトを読み取ってから元に戻すことにより、ストリームが読み取り可能かどうかをテストするための潜在的な探索手段ですが、私のテストでは、期待どおりに動作しません。つまりchar = c.read_nonblock(1); c.ungetc(char); wire_data = c.read_partial(10)wire_data == char接続バッファーcharにバッファ。

4

1 に答える 1

1

いつものように問題を書き出すことで、私は解決策を見つけるのを手伝ってくれました。readpartialステートマシンで呼び出す代わりに、を呼び出すことができますread_nonblockread_nonblock読み取るものがない場合は例外をスローします。この例外をキャッチして、選択ループのブロックを解除できます。

于 2013-03-15T07:17:36.303 に答える