PHP+shellでマルチスレッドを実装する方法
まず、簡単な php コードを書きます。スクリプトの実行時間を長くして効果を確認しやすくするために、しばらくスリープします (笑)。まずはtest.phpのコードを見てみましょう: ls
PHPコード:
for ($i=0;$i<10;$i++) {
エコー $i;
睡眠(10);
}
?>
シェルスクリプトのコードを見てください、とてもシンプルです
#!/bin/bash
1 2 3 4 5 6 7 8 9 10 の私のために
する
/usr/bin/php -q /var/www/html/test.php &
完了しました
PHP コードをリクエストする行に & 記号があることに気づきましたか? これがないと、マルチスレッドを実行できないため、サービスがバックグラウンドで実行されることを意味します。シェルの各ループで使用する必要はありません。次のファイルをリクエストする前に、すべての PHP コードが実行されるのを待ちます。これにより、以下のシェルを実行して効果を確認できます。ここには 10 個の test.php プロセスが表示され、再度実行してから、Linux タイマーがこのシェルを定期的に要求します。これは、バッチ ダウンロードなど、マルチスレッドを必要とするタスクを処理する場合に非常に便利です。
WEBサーバーを使用してphpでマルチスレッドを実装する
今ファイル a.php を実行しているとします。しかし、プログラム内で WEB サーバーに別の b.php を実行するようリクエストすると、2 つのファイルが同時に実行されます (追記: リンクリクエストが送信された後)。 , WEB クライアントが終了したかどうかに関係なく、サーバーが実行します)
実行したいのは別のファイルではなく、このファイル内のコードの一部である場合があります。どうすればよいでしょうか?
実際、パラメータは a.php が実行するプログラムを制御するために使用されます。
以下の例を見てください:
//a.php,b.php
PHPコード:---------------------------------------------- -- ----------------------------------
関数 runThread()
{
$fp = fsockopen('localhost', 80, $errno, $errmsg);
//理解できない場合は、RFC の定義を参照してください
fclose($fp);
}
関数a()
{
$fp = fopen('result_a.log', 'w');
fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
fclose($fp);
}
関数 b()
{
$fp = fopen('result_b.log', 'w');
fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
fclose($fp);
}
If(!isset($_GET['act'])) $_GET['act'] = 'a';
If($_GET['act'] == 'a')
{
runThread();
a();
}
else if($_GET['act'] == 'b') b();
?>
-------------------------------------------------- ----------------------------------
result_a.log と result_b.log を開いて 2 つのファイルのアクセス時間を比較すると、これら 2 つは実際に異なるスレッドで実行されていることがわかります。
上記は単なる例であり、他の形式に改良することができます。
PHP でマルチスレッドが使用できるようになったので、問題が発生します。それは、PHP 自体がマルチスレッドをサポートしていないことです。それでは、どうすればよいでしょうか。
1. 競合を避けるために、同じリソースにアクセスしないようにしてください。ただし、データベースは同時操作をサポートしているため、マルチスレッド PHP で同じファイルにデータを書き込まないでください。その場合は、flock を呼び出してファイルをロックするなど、同期に他の方法を使用します。または、一時ファイルを作成し、別のスレッドでファイルが消えるのを待ちます。 これは、次と同等です。この一時ファイルが存在するということは、スレッドが実際に動作していることを意味します
このファイルがもう存在しない場合は、他のスレッドがそのファイルを解放したことを意味します。
2. fputs の実行後に runThread が取得するソケットからデータを読み取らないようにします。これは、fgets のような関数がすぐにデータを読み書きする場合に、ノンブロッキング モードを使用する必要があるためです。ブロッキングモードが使用されている場合、プログラムはマルチスレッドではないため、次のプログラムを実行する前に、データの交換が必要な場合は、外部ファイルで完了する必要があります。本当にやりたい場合は、socket_set_nonblock ($fp) を使用してください。
ここまで述べましたが、この方法を使用する必要があるのはどのような場合ですか?
答えは「はい」です。ご存知のとおり、ネットワーク リソースを常に読み取るアプリケーションでは、ネットワークの速度がボトルネックになります。この方法を採用すると、複数のスレッドで同時に異なるページを読み取ることができます。
8848やsoasoなどのショッピングモールサイトから情報を検索できるプログラムを作りました。アリババのウェブサイトからビジネス情報や企業ディレクトリを読み取るプログラムもあり、この技術も利用されています。 どちらのプログラムも、情報を読み取ってデータベースに保存するためにサーバーに継続的に接続する必要があるためです。 この技術を活用することで、応答待ちのボトルネックを解消します。
php でマルチスレッドをシミュレートする 3 つの方法
PHP 言語自体はマルチスレッドをサポートしていません。一般的に、PHP の優れたパートナーのマルチスレッド機能を利用するものをまとめました。 LINUX と APACHE、LAMP
また、これはシミュレートされているため、実際にはマルチプロセスではありません。プロセスとスレッドは 2 つの異なる概念です。以下のメソッドはすべてインターネットから見つかります。
1. LINUXオペレーティングシステムを使用しますfor ($i=0;$i<10;$i++) { エコー $i;
睡眠(5);
}
?>
上記をtest.phpとして保存し、SHELLコードを記述します
1 2 3 4 5 6 7 8 9 10 の私のために
する
php -q test.php &
完了しました
2. fork 子プロセスを使用します (実際には、LINUX オペレーティング システムも使用します)
;
$intNum = 10 /// プロセスの総数
;
$pids = array() /// 処理 PID 配列
echo (「開始」);
for($i = 0; $i <$intNum; $i++) {
$pids[$i] = pcntl_fork();/// 子プロセスを生成し、現在行からテスト実行コードを開始し、親プロセスのデータ情報は引き継がない
if(!$pids[$i]) {
// サブプロセスプロセスコードsegment_Start
$str="";
睡眠(5+$i);
for ($j=0;$j<$i;$j++) {$str.="*";}
echo "$i -> " . time() . " $str n";
exit();
// サブプロセスプロセスコードsegment_End
}
}
if ($bWaitFlag)
{
for($i = 0; $i
pcntl_waitpid($pids[$i], $status, WUNTRACED);
echo "wait $i -> " . "n";
}
}
echo (「終了」);
?>
3. WEB サーバーを使用する場合、PHP はマルチスレッドをサポートしませんが、APACHE はサポートします (笑)。
ドキュメント a.php を実行しているとします。しかし、プログラム内で別の b.php を実行するように WEB サーバーにリクエストします。
もちろん、マルチスレッドが必要な部分はJAVAに任せて、PHPで呼び出すこともできます(笑)
system('java multiThread.java'); ?>