回答:
私が知っている利用可能なものは何もありません。次善の策は、CLIを介して1つのスクリプトで別のスクリプトを実行することですが、それは少し初歩的です。何をしようとしているか、どれほど複雑かによって、これはオプションになる場合も、そうでない場合もあります。
pthreads拡張機能のPHPマニュアルから:
pthreadsは、PHPでユーザーランドのマルチスレッドを可能にするオブジェクト指向APIです。Webまたはコンソールを対象としたマルチスレッドアプリケーションを作成するために必要なすべてのツールが含まれています。PHPアプリケーションは、スレッド、ワーカー、スタッカブルを作成、読み取り、書き込み、実行、同期できます。
これが信じられないほど信じられないほど、それは完全に本当です。今日、PHPは、試してみたい人のためにマルチスレッド化できます。
PHP4の最初のリリース、2000年5月22日、PHPはスレッドセーフアーキテクチャで出荷されました。これは、マルチスレッドSAPI(Server API)環境で別個のスレッドでインタプリタの複数のインスタンスを実行する方法です。過去13年間、このアーキテクチャの設計は維持され、進歩してきました。それ以来、世界最大のWebサイトで本番環境で使用されています。
ユーザーランドでのスレッディングは、PHPチームにとって決して問題ではありませんでしたが、今日もそうです。PHPがビジネスを行う世界では、ハードウェアを追加するという、定義されたスケーリング方法がすでに存在していることを理解する必要があります。長年にわたってPHPが存在し、ハードウェアがどんどん安くなっているため、これはPHPチームにとってますます懸念事項ではなくなりました。値段は安くなりましたが、さらに強力になりました。今日、私たちの携帯電話とタブレットはデュアルおよびクアッドコアアーキテクチャとそれに対応する十分なRAMを備えています。デスクトップとサーバーは通常8または16コア、16および32ギガバイトのRAMを備えていますが、常に2つを備えているとは限りません予算の範囲内で2つのデスクトップを持つことは、ほとんどの人にとってめったに役に立ちません。
さらに、PHPはプログラマーではない人のために書かれたもので、多くの愛好家のネイティブタンです。PHPが非常に簡単に採用される理由は、PHPが学習および記述が容易な言語だからです。PHPが今日非常に信頼できる理由は、PHPの設計に費やされる膨大な量の作業と、PHPグループによるすべての単一の決定によるものです。これらすべての年の後に、それは信頼性と純粋な偉大さがスポットライトでそれを保ちます。ライバルが時間やプレッシャーに陥っているところ。
マルチスレッドプログラミングは、最も一貫性のある信頼性の高いAPIを使用していても、ほとんどの場合簡単ではありません。さまざまなことを検討する必要があり、多くの誤解があります。PHPグループは、ユーザーランドのマルチスレッド化がコア機能であることを望んでいません。誰にとっても、PHPは複雑であってはなりません。
すべてを考慮した上で、PHPが本番環境の準備済みでテスト済みの機能を利用できるようにすることで得られるメリットはまだあります。本当に必要なタスクはありません。
pthreadsは、探索したい人のために、ユーザーがPHPアプリケーションをマルチスレッド化できるAPIを実現します。それはAPIが非常に進行中の作業であり、安定性と完全性のベータレベルを指定しました。
PHPが使用するライブラリの一部はスレッドセーフではないことはよく知られています。pthreadがこれを変更できないこと、および試そうとしないことはプログラマーには明らかです。ただし、インタプリタの他のスレッドセーフなセットアップと同様に、スレッドセーフなライブラリはすべて使用できます。
pthreadsはPosixスレッド(Windowsでも)を利用します。プログラマーが作成するのは実際の実行スレッドですが、それらのスレッドが有用であるためには、PHPを認識している必要があります-ユーザーコードの実行、変数の共有、および有用な通信手段の許可(同期)。したがって、すべてのスレッドはインタープリターのインスタンスで作成されますが、マルチスレッドのサーバーAPI環境と同様に、そのインタープリターはインタープリターの他のすべてのインスタンスから分離されています。pthreadsは、適切かつ安全な方法でギャップを埋めようとします。Cのスレッドのプログラマーの懸念の多くは、pthreadのプログラマーにはまったくありません。設計上、pthreadは読み取り時にコピーされ、書き込み時にコピーされるため(RAMは安価です)、2つのインスタンスが同じ物理データを操作することはありません。ただし、どちらも別のスレッドのデータに影響を与える可能性があります。
読み取り時にコピーし、書き込み時にコピーする理由:
public function run() {
...
(1) $this->data = $data;
...
(2) $this->other = someOperation($this->data);
...
}
(3) echo preg_match($pattern, $replace, $thread->data);
(1)読み取りおよび書き込みロックがpthreadオブジェクトデータストアに保持されている間、データはメモリ内の元の場所からオブジェクトストアにコピーされます。pthreadは変数のrefcountを調整しません。Zendは、それ以上の参照がない場合、元のデータを解放できます。
(2)someOperationの引数は、オブジェクトストアを参照します。これは、格納された元のデータであり、それ自体が(1)の結果のコピーであり、エンジンのzvalコンテナーに再度コピーされますが、これが発生すると、読み取りロックが保持されます。オブジェクトストア、ロックが解放され、エンジンは関数を実行できます。zvalが作成されると、参照カウントは0になり、他の参照が存在しないため、操作の完了時にエンジンがコピーを解放できるようになります。
(3)preg_matchの最後の引数がデータストアを参照し、読み取りロックが取得され、(1)で設定されたデータがzvalにコピーされ、refcountが0になります。ロックが解除され、preg_matchの呼び出しが処理されますデータのコピー、それ自体が元のデータのコピーです。
知っておくべきこと:
データが格納されるオブジェクトストアのハッシュテーブルは、スレッドセーフであり
、PHPに同梱されているZendのTsHashTableに基づいています。
オブジェクトストアには読み取りロックと書き込みロックがあり、TsHashTableには追加のアクセスロックが用意されているため、必要に応じて(PHPエンジンがプロパティを参照するときにvar_dump / print_r、プロパティに直接アクセスできます)、pthreadはTsHashTableを操作できます。定義されたAPIの外。
ロックは、コピー操作が行われている間のみ保持され、コピーが作成されると、適切な順序でロックが解除されます。
これの意味は:
書き込みが発生すると、読み取りおよび書き込みロックだけでなく、追加のアクセスロックも保持されます。テーブル自体はロックされています。別のコンテキストがテーブルをロック、読み取り、書き込み、または影響する可能性はありません。
読み取りが発生すると、読み取りロックが保持されるだけでなく、追加のアクセスロックも保持され、再びテーブルがロックダウンされます。
2つのコンテキストがオブジェクトストアから同じデータに物理的にも同時にもアクセスすることはできませんが、参照のあるコンテキストで行われた書き込みは、参照のあるコンテキストで読み取られたデータに影響します。
これは何も共有しないアーキテクチャであり、存在する唯一の方法は共存することです。少し精通している人はそれを見るでしょう、ここで多くのコピーが行われている、そして彼らはそれが良いことかどうか疑問に思うでしょう。動的ランタイム内ではかなりの量のコピーが行われます。それが動的言語のダイナミクスです。1つのオブジェクトを適切に制御できるため、pthreadはオブジェクトのレベルで実装されますが、メソッド(プログラマが実行するコード)には、ロックやコピーのない別のコンテキスト(ローカルメソッドスコープ)があります。pthreadsオブジェクトの場合のオブジェクトスコープは、コンテキスト間でデータを共有する方法として扱う必要があります。それが目的です。これを念頭に置いて、必要でない限り、オブジェクトストアのロックを回避する手法を採用できます。
PHPで使用できるライブラリと拡張機能のほとんどはサードパーティの薄いラッパーであり、PHPのコア機能はある程度同じです。pthreadsは、Posixスレッドの薄いラッパーではありません。これは、Posixスレッドに基づくスレッドAPIです。PHPでスレッドを実装しても、ユーザーが理解していない、または使用できないのは意味がありません。ミューテックスとは何か、またはミューテックスについて何も知らない人が、スキルとリソースの両方の面で、ミューテックスが持っているすべてのものを利用できないはずがあるという理由はありません。オブジェクトはオブジェクトのように機能しますが、2つのコンテキストが衝突する場合は常に、pthreadは安定性と安全性を提供します。
Javaで作業したことがある人は誰でも、pthreadsオブジェクトとJavaでのスレッド化の類似点を確認できます。同じ人々は、ConcurrentModificationExceptionと呼ばれるエラーを見たことがあるでしょう。同時に。それが存在する理由は理解していますが、リソースができるだけ安価であり、ランタイムがユーザーに対して安全性を達成できる正確かつ唯一のタイミングで並行性を検出できるという事実と相まって、困惑しています実行とデータへのアクセスを管理するのではなく、実行時に致命的なエラーをスローします。
そのような愚かなエラーはpthreadによって出力されることはなく、APIはスレッド化を可能な限り安定させ、互換性を持たせるように作成されていると思います。
マルチスレッドは新しいデータベースの使用とは異なります。pthreadに同梱されているマニュアルと例のすべての単語に細心の注意を払う必要があります。
最後に、PHPマニュアルから:
pthreadsは、非常に良い結果をもたらす実験でした。その制限や機能はいつでも変更される可能性があります。それが実験の性質です。これは、多くの場合、実装によって課せられる制限ですが、正当な理由があるためです。pthreadの目的は、任意のレベルでPHPのマルチタスクに使用可能なソリューションを提供することです。pthreadが実行する環境では、安定した環境を提供するためにいくつかの制限事項があります。
ウィルコが提案した例を以下に示します。
$cmd = 'nohup nice -n 10 /usr/bin/php -c /path/to/php.ini -f /path/to/php/file.php action=generate var1_id=23 var2_id=35 gen_id=535 > /path/to/log/file.log & echo $!';
$pid = shell_exec($cmd);
基本的に、これはコマンドラインでPHPスクリプトを実行しますが、すぐにPIDを返し、バックグラウンドで実行します。(エコー$!は、PID以外の何も返されないことを保証します。)これにより、必要に応じてPHPスクリプトを続行または終了できます。これを使用したとき、ユーザーを別のページにリダイレクトしました。5〜60秒ごとに、レポートがまだ実行されているかどうかを確認するためにAJAX呼び出しが行われます。(gen_idとそれに関連するユーザーを格納するテーブルがあります。)チェックスクリプトは以下を実行します。
exec('ps ' . $pid , $processState);
if (count($processState) < 2) {
// less than 2 rows in the ps, therefore report is complete
}
このテクニックに関する短い投稿がここにあります:http : //nsaunders.wordpress.com/2007/01/12/running-a-background-process-in-php/
つまり、phpにはマルチスレッドがありますが、代わりにマルチプロセッシングを使用する必要があります。
スレッドとプロセスの違いについては常に少し混乱があるので、両方について簡単に説明します。
phpで新しいプロセス(新しいスレッドも含む)を作成することで、並列計算を実現できます。スレッドが多くの通信や同期を必要としない場合は、これが選択です。これは、プロセスが分離され、互いの作業を妨げることがないためです。1つがクラッシュしても、それは他のユーザーには関係ありません。大量の通信が必要な場合は、「マルチスレッド化」を読むか、悲しいことに、別のプログラミング言語を使用することを検討してください。プロセス間通信と同期により多くの複雑さが生じるためです。
PHPでは、新しいプロセスを作成する2つの方法があります。
OSに任せてください。オペレーティングシステムに新しいプロセスを作成し、その中で新しい(または同じ)phpスクリプトを実行するように指示できます。
以下のためのLinuxの次を使用するか検討することができダリル・ハインの答えを:
$cmd = 'nice php script.php 2>&1 & echo $!';
pclose(popen($cmd, 'r'));
以下のための窓あなたはこれを使用することがあります。
$cmd = 'start "processname" /MIN /belownormal cmd /c "script.php 2>&1"';
pclose(popen($cmd, 'r'));
フォークを使用して自分で行う:phpは、関数pcntl_fork()を使用してフォークを使用することもできます。これを行う方法に関する優れたチュートリアルはここにありますが、フォークは人類に対する犯罪であり、特にoopに対する犯罪であるため、使用しないことを強くお勧めします。
マルチスレッドを使用すると、すべてのスレッドがリソースを共有するため、多くのオーバーヘッドなしでスレッド間の通信と同期を簡単に行うことができます。一方、競合状態とデッドロックは簡単に生成できますが、デバッグが非常に難しいため、何をしているのかを知る必要があります。
標準のphpはマルチスレッドを提供しませんが、実際に-pthreadsを実行する(実験的)拡張があります。そのapiドキュメントはphp.netに作成しました。これを使えば、実際のプログラミング言語でできるように、次のようなことができます。
class MyThread extends Thread {
public function run(){
//do something time consuming
}
}
$t = new MyThread();
if($t->start()){
while($t->isRunning()){
echo ".";
usleep(100);
}
$t->join();
}
以下のためのlinuxがあるインストールガイドのstackoverflowの時に右ここに。
以下のためのウィンドウになりましたものがあります。
[phpDirectory] /php.iniを編集し、次の行を挿入します
extension=php_pthreads.dll
上記のスクリプトを使用して、コメントがある場所にスリープまたは何かを置いてテストします。
そして今大きなBUT:これは実際に機能しますが、phpはもともとマルチスレッド用に作成されていませんでした。スレッドセーフバージョンのphpが存在し、v5.4の時点ではバグはほとんどないようですが、マルチスレッド環境でphpを使用することは、phpマニュアルではまだ推奨されていません(ただし、マニュアルを更新しなかっただけかもしれません)これ、まだ)。より大きな問題は、多くの一般的な拡張機能がスレッドセーフではないことです。したがって、このphp拡張機能でスレッドを取得する可能性がありますが、依存している関数はまだスレッドセーフではないため、自分で記述していないコードで競合状態やデッドロックなどが発生する可能性があります...
pcntl_fork()を使用して、スレッドに似たものを実現できます。技術的にはそれは別個のプロセスであるため、2つの間の通信はスレッドでは単純ではなく、PHPがApacheによって呼び出された場合は機能しないと思います。
pcntl_fork()
あなたが探しているものですが、そのプロセスはスレッドではありません。したがって、データ交換の問題が発生します。それらを解決するには、phpのセマフォ関数(http://www.php.net/manual/de/ref.sem.php)を使用できます。メッセージキューは、共有メモリセグメントよりも最初は少し簡単かもしれません。
とにかく、私が開発しているWebフレームワークで使用している戦略で、Webページのリソースを大量に消費するブロックを(おそらく外部要求で)並列に読み込みます。ジョブキューを実行して、待機しているデータを確認してからフォークします。すべてのプロセスのジョブをオフにします。完了すると、親プロセスがアクセスできる一意のキーの下にあるapcキャッシュにデータを保存します。すべてのデータが存在すると、それは継続します。usleep()
apacheではプロセス間通信ができないため、待機に単純を使用しています(子供は親との接続を失い、ゾンビになります...)。だから、これは私に最後のことをもたらします:すべての子供を自殺することが重要です!プロセスをフォークするがデータを保持するクラスもあります。私はそれらを調べませんでしたが、zendフレームワークには1つあり、通常は低速ですが確実にコードを実行します。あなたはそれをここで見つけることができます:
http://zendframework.com/manual/1.9/en/zendx.console.process.unix.overview.html
彼らはshmセグメントを使用していると思います!最後に、このZend Webサイトにエラーがあり、例に小さな間違いがあります。
while ($process1->isRunning() && $process2->isRunning()) {
sleep(1);
}
should of course be:
while ($process1->isRunning() || $process2->isRunning()) {
sleep(1);
}
https://github.com/krakjoe/pthreadsで非常に有望に見えるPThreadsに基づいてactivleyで開発されているThreading拡張機能があります
単なる更新です。PHPの連中がサポートスレッドに取り組んでいるようです。
これへのリンクは次のとおりです。http: //php.net/manual/en/book.pthreads.php
PHPスレッディングクラスがあり、2年以上本番環境で問題なく実行されています。
編集:これは作曲家ライブラリとして、そして私のMVCフレームワークであるHazaar MVCの一部として利用できるようになりました。
私はこれが古い質問であることを知っていますが、http://phpthreadlib.sourceforge.net/を見ることができます
双方向通信、Win32のサポート、拡張機能は必要ありません。
appserver
テクディビジョンから聞いたことがありますか?
それはphpで書かれており、高トラフィックのphpアプリケーションのマルチスレッドを管理するappserverとして機能します。まだベータ版ですが、非常に有望です。
pcntl_fork()
Apacheから呼び出された場合、これ()が機能するかどうか誰でも知っていますか?