2

私は stream_select() を使用していますが、数秒後に0個の記述子を返し、まだ読み取るデータがある間に関数を返します。

珍しいことですが、タイムアウトを 0 に設定すると、記述子の数が常にゼロになります。

$num = stream_select($read, $w, $e, 0);
4

4 に答える 4

4

stream_select() はループで使用する必要があります

stream_select()関数は基本的に、最初の 3 つの引数で指定したストリーム セレクターをポーリングするだけです。つまり、次のイベントのいずれかが発生するまで待機します。

  • 何らかのデータが到着
  • または、データを取得せずにタイムアウト ($tv_sec と $tv_usec で設定) に達した場合。

したがって、戻り値として0 を受け取ることは完全に正常であり、現在のポーリング サイクルで新しいデータがなかったことを意味します。

関数を次のようなループに入れることをお勧めします。

$EOF = false;

do {
    $tmp  = null;
    $ready = stream_select($read, $write, $excl, 0, 50000);

    if ($ready === false ) {
        // something went wrong!!
        break;
    } elseif ($ready > 0) {
        foreach($read as $r) {
            $tmp .= stream_get_contents($r);
            if (feof($r)) $EOF = true;
        }

        if (!empty($tmp)) {
            //
            // DO SOMETHING WITH DATA
            //
            continue;
        }
    } else {
        // No data in the current cycle
    }
} while(!$EOF);

この例では、スクリプトは入力ストリーム以外のすべてを完全に無視することに注意してください。また、「if」ステートメントの 3 番目のセクションは完全にオプションです。

于 2016-05-30T13:18:39.667 に答える
3

0数値またはFALSEブール値を返しますか? FALSE何らかのエラーが発生したことを意味しますが、タイムアウトが原因でゼロになるか、ストリームで興味深いことが何も起こらなかったため、新しい選択などを行う必要があります。

これは、チェックしてすぐに戻るため、タイムアウトがゼロの場合に発生する可能性があると思います。また、 stream-select に関する PHP マニュアルを読むと、ゼロ タイムアウトの使用に関する次の警告が表示されます。

タイムアウト値 0 を使用すると、ストリームのステータスを即座にポーリングできますが、ループでタイムアウト値 0 を使用すると、スクリプトが CPU 時間を消費しすぎるため、お勧めできません。

これが TCP ストリームであり、接続のクローズを確認したい場合は、freadetc からの戻り値をチェックして、他のピアが接続をクローズしたかどうかを判断する必要があります。readストリーム配列引数について:

読み取り配列にリストされたストリームは、文字が読み取り可能になるかどうかを監視します (より正確には、読み取りがブロックされないかどうかを確認します。特に、ストリーム リソースはファイルの終わりでも準備ができています。 fread() は長さゼロの文字列を返します)。

于 2012-08-03T17:53:23.453 に答える
0

http://www.php.net/stream_select

現在の Zend Engine の制限により、NULL などの定数修飾子を、このパラメーターが参照によって渡されることを期待する関数にパラメーターとして直接渡すことはできません。代わりに、一時変数または左端のメンバーが一時変数である式を使用します。

<?php $e = NULL; stream_select($r, $w, $e, 0); ?>
于 2012-08-03T16:08:19.140 に答える