0

バックグラウンド プロセスとして実行される PHP スクリプトがあります。このスクリプトは、単純に fopen を使用して Twitter ストリーミング API から読み取ります。基本的に、決して終わらない http 接続です。残念ながら、スクリプトは独自のものであるため、投稿できません。Ubuntu のスクリプトは正常に実行され、CPU をほとんど使用しません。ただし、BSD では、スクリプトは常にほぼ 100% の CPU を使用します。スクリプトは両方のマシンで問題なく機能しており、まったく同じスクリプトです。これを修正するために正しい方向に私を向けるかもしれない何かを誰かが考えることができますか? これは、一貫してバックグラウンドで実行するように作成した最初の PHP スクリプトです。

スクリプトは無限ループで、毎分データを読み取り、json ファイルに書き込みます。スクリプトは、再接続が発生するたびに MySQL データベースに書き込みます。これは通常、数日実行した後で行われます。スクリプトは他に何もせず、それほど長くはありません。BSD や、無限ループを実行する PHP スクリプトを書いた経験はほとんどありません。提案をお寄せいただきありがとうございます。これが別の StackExchange に属しているかどうかをお知らせください。質問が非常に漠然としていることを認識しているため、質問にはできるだけ早く答えようとします。

4

3 に答える 3

1

スクリプトを見ずに決定的な答えを出すのは非常に困難ですが、スクリプトがデータを適切に待機していることを確認する必要があります。絶対にすべきではないことは、ファイル ポインターの呼び出しstream_set_timeout($fp, 0);または呼び出しです。stream_set_blocking($fp, 0);

レースを回避する必要があるこのようなことを行うためのスクリプトの基本的な構造は、次のようになります。

// Open the file pointer and set blocking mode
$fp = fopen('http://www.domain.tld/somepage.file','r');
stream_set_timeout($fp, 1);
stream_set_blocking($fp, 1);

while (!feof($fp)) { // This should loop until the server closes the connection

  // This line should be pretty much the first line in the loop
  // It will try and fetch a line from $fp, and block for 1 second
  // or until one is available. This should help avoid racing
  // You can also use fread() in the same way if necessary
  if (($str = fgets($fp)) === FALSE) continue;

  // rest of app logic goes here

}

sleep()/を使用usleep()して競合を回避することもできますが、より良いアプローチは、ブロッキング関数呼び出しに依存してブロッキングを行うことです。ある OS では機能するが別の OS では機能しない場合は、上記のようにブロック モード/動作を明示的に設定してみてください。

fopen()HTTP URL を渡す呼び出しでこれが機能しない場合は、PHP の HTTP ラッパー実装に問題がある可能性があります。これを回避するにはfsockopen()、リクエストを自分で使用して処理することができます。これは、特に 1 つのリクエストを送信し、一定のストリーム レスポンスを読み取るだけでよい場合は、それほど難しくありません。

于 2011-10-13T20:28:31.757 に答える
1

あなたの機能の1つがLinuxで一時的にブロックされているように思えますが、BSDではありません。スクリプトを見ないと具体的に理解するのは難しいですが、私が提案することの 1 つはusleep()、次のループ反復の前にa を追加することです。

usleep(100000); //Sleep for 100ms

長いスリープは必要ありません... CPU を 100% 使用しないようにするだけで十分です。

編集:あなたは今これをバックグラウンドで実行する良い方法がないと言ったので、スクリプトを「デーモン化」するためにこのチュートリアルをチェックすることをお勧めします。これを行うための便利なコードが含まれています。ファイルを作成することもできinit.dます。

于 2011-10-13T20:27:45.413 に答える
0

コードはどのように見え、実際の読み取りはどのようになりますか? 何かが得られるまでソケットをハンマーで叩きますか?

これに対処するための本当に効果的な方法の 1 つは、libevent 拡張機能を使用することですが、それは気が弱い人向けではありません。

于 2011-10-13T20:28:47.627 に答える