pthreads はオブジェクト指向の API で、ユーザーランドでのマルチスレッド処理を PHP で行うためのものです。 マルチスレッドアプリケーションを作るのに必要な、あらゆるツールが含まれています。 PHP アプリケーションで、Thread や Worker そして Threaded を作ったり読み書きしたり実行したりできるようになります。
A Threaded Object: A Threaded Object forms the basis of the functionality that allows pthreads to operate. It exposes synchronization methods and some useful interfaces for the programmer.
Thread オブジェクト: ユーザーがスレッドを実装するには、pthreads が用意した Thread の宣言を継承して run メソッドを実装します。 Thread を参照すれば、あらゆるコンテキストから任意のメンバーの読み書きができ、 すべての public メソッドおよび protected メソッドを任意のコンテキストで実行できます。 run メソッドは、この実装オブジェクトの start メソッドを呼んだコンテキスト (Thread あるいは Process) とは別のスレッドで実行されます。 スレッドを作ったコンテキストだけが、スレッドの start や join を行えます。
Worker オブジェクト: ワーカースレッドは永続的な状態を保持し、start を呼んだ時点からオブジェクトがスコープ外に消えるまで (あるいは明示的に shutdown するまで) 使えます。 このオブジェクトを参照する任意のコンテキストから、 オブジェクトを Worker に渡せます。これを、Worker が別スレッドで実行します。 Worker の run メソッドは、あらゆるオブジェクトがスタックに積まれる前に実行されます。 そのため、オブジェクトで必要となるリソースの初期化に使えます。
プール: ワーカースレッドのプールを使って、プログラマーが宣言したワーカークラス群の間で Threaded オブジェクトを分散させることができます。 Pool クラスがこの機能を実装しており、きちんと参照を管理してくれます。 これは v1.0.0 で導入されました。複数スレッドを扱う際に最も簡単かつ効率的な方法です。
プールは通常の PHP オブジェクトなので、そのインスタンスをコンテキスト間で共有してはいけません。
同期処理: pthreds が用意するすべてのオブジェクトには、 (Java プログラマーならおなじみの) ::wait と ::notify による同期処理が組み込まれています。 あるオブジェクトの ::wait を呼ぶと、別のコンテキストから同じオブジェクトの ::notify が呼ばれるのを待つようになります。 これを使えば、PHP 内のスレッド化されたオブジェクト (Threaded Object) どうしで強力な同期処理ができるようになります。
Any objects that are intended for use in the multi-threaded parts of your application should extend Threaded.
メソッドの修飾子: スレッド化されたオブジェクトの protected メソッドは、pthreads がプロテクトします。 そしてこのメソッドは、同時に複数のコンテキストからは呼べなくなります。 スレッド化されたオブジェクトの private メソッドは、 実行中のそのオブジェクトの中からしか呼べません。
データストレージ: 目安として、シリアライズ可能なデータ型なら何でも、スレッド化されたオブジェクトのメンバーとして使えます。 そのオブジェクトへの参照を持つあらゆるコンテキストから、メンバーの読み書きができます。 すべてのデータ型がシリアライズされるわけではなく、基本型はそのままの形式で格納されます。 それ以外の複雑な型や配列、スレッド化されていないオブジェクトは、シリアライズして格納されます。 これらは、参照を持つ任意のコンテキストから、スレッド化されたオブジェクトへの読み書きができます。 スレッド化されたオブジェクトを例外として、 あるスレッド化されたオブジェクトのメンバーを設定するために使うあらゆる参照は、 そのスレッド化されたオブジェクト内の参照とは区別されます。 同じデータを、いつでもどのコンテキストからでも、 スレッド化されたオブジェクトから直接読み込めます。
静的メンバー: 新しいコンテキスト (Thread あるいは Worker) を作るときには、一般的にそれらはコピーされます。 しかし、リソースおよび内部状態を持つオブジェクトは、安全性を考慮して null 化されます。 これを、一種のスレッドローカルストレージとして使えます。 たとえば、データベースサーバーへの接続情報と接続そのものを静的メンバーとして持つクラスがあるとします。 コンテキストを開始するときには接続情報だけがコピーされ、接続自体はコピーされません。 新しいコンテキスト上ではそのコンテキストを作ったオブジェクトと同じ方法で接続を立ち上げることができ、 その接続を同じ場所に格納しても元のコンテキストには何も影響を及ぼしません。
print_r や var_dump などのオブジェクトのデバッグ用関数を実行するきには、 再帰の制限には含まれません。
注意:
リソース: PHP のリソースを定義している拡張モジュールは、この手の環境で扱うには不十分です。 pthreads はリソースをコンテキスト間で共有するための対策を用意していますが、 大半のリソース型は安全には扱えません。 コンテキスト間でリソースを共有するときには、いくら注意してもしすぎることはありません。
pthreads の実行環境を安定させるには、いくつかの制限は必要になるのです。