pthreads
PHP Manual

導入

pthreads はオブジェクト指向の API で、ユーザーランドでのマルチスレッド処理を PHP で行うためのものです。 ウェブやコンソールをターゲットにしたマルチスレッドアプリケーションを作るのに必要な、あらゆるツールが含まれています。 PHP アプリケーションで、Thread や Worker そして Stackable を作ったり読み書きしたり実行したりできるようになります。

Thread オブジェクト: ユーザーがスレッドを実装するには、pthreads が用意した Thread の宣言を継承します。 Thread を参照すれば、あらゆるコンテキストから任意のメンバーの読み書きができ、 すべての public メソッドおよび protected メソッドを任意のコンテキストで実行できます。 run メソッドは、この実装オブジェクトの start メソッドを呼んだコンテキスト (Thread あるいは Process) とは別のスレッドで実行されます。 スレッドを作ったコンテキストだけが、スレッドの start や join を行えます。

Worker オブジェクト: ワーカースレッドは永続的な状態を保持し、start を呼んだ時点からオブジェクトがスコープ外に消えるまで (あるいは明示的に shutdown するまで) 使えます。 このオブジェクトを参照する任意のコンテキストから、 Stackable 型のオブジェクトを Worker に渡せます。これを、Worker が別スレッドで実行します。 Worker の run メソッドは、あらゆるオブジェクトがスタックに積まれる前に実行されます。 そのため、Stackable で必要となるリソースの初期化に使えます。

Stackable オブジェクト: Stackable オブジェクトは、実行時に Worker の読み書きや実行ができ、 実行前に適切なオブジェクトへの参照を提供します。 さらに、Stackable への参照があるあらゆるコンテキストは、実行前と実行後の間にそのメソッドの読み書きや実行ができます。

同期処理: pthreds が用意するすべてのオブジェクトには、 (Java プログラマーならおなじみの) ::wait と ::notify による同期処理が組み込まれています。 あるオブジェクトの ::wait を呼ぶと、別のコンテキストから同じオブジェクトの ::notify が呼ばれるのを待つようになります。 これを使えば、PHP 内のスレッド化されたオブジェクト (Threaded Object) どうしで強力な同期処理ができるようになります。

スレッド化されたオブジェクトって? Stackable や Thread、そして Worker はスレッド化された stdClass とみなせて、実際そのように使えます。 Thread、Worker そして Stackable のいずれも、参照を含むあらゆるコンテキストで同じように振舞います。 マルチスレッド対応の部分で使うことを想定したあらゆるオブジェクトは、 Stackable か Thread あるいは Worker のいずれかを継承しなければいけません。 つまり、run メソッドを実装する必要があるけれども、それが必ずしも実行されるとは限らないということです。 マルチスレッド環境で使われるオブジェクトの多くは、実行されることを意図しています。 つまり、参照付きのあらゆるコンテキスト (Thread/Worker/Stackable/Process) は、スレッド化されたオブジェクトのメンバーの読み書きや実行を、 実行前/実行中/実行後 にできるということです。

メソッドの修飾子: スレッド化されたオブジェクトの protected メソッドは、pthreads がプロテクトします。 そしてこのメソッドは、同時に複数のコンテキストからは呼べなくなります。 スレッド化されたオブジェクトの private メソッドは、 実行中のそのオブジェクトの中からしか呼べません。

データストレージ: 目安として、シリアライズ可能なデータ型なら何でも、スレッド化されたオブジェクトのメンバーとして使えます。 そのオブジェクトへの参照を持つあらゆるコンテキストから、メンバーの読み書きができます。 すべてのデータ型がシリアライズされるわけではなく、基本型はそのままの形式で格納されます。 それ以外の複雑な型や配列、スレッド化されていないオブジェクトは、シリアライズして格納されます。 これらは、参照を持つ任意のコンテキストから、スレッド化されたオブジェクトへの読み書きができます。 スレッド化されたオブジェクトを例外として、 あるスレッド化されたオブジェクトのメンバーを設定するために使うあらゆる参照は、 そのスレッド化されたオブジェクト内の参照とは区別されます。 同じデータを、いつでもどのコンテキストからでも、 スレッド化されたオブジェクトから直接読み込めます。

静的メンバー: 新しいコンテキスト (Thread あるいは Worker) を作るときには、 単純型の静的メンバーだけがコピーされます。 リソースやオブジェクトは、静的なクラスメンバーからスレッドのコンテキストにはコピーされません。 これを、一種のスレッドローカルストレージとして使えます。 たとえば、データベースサーバーへの接続情報と接続そのものを静的メンバーとして持つクラスがあるとします。 コンテキストを開始するときには接続情報だけがコピーされ、接続自体はコピーされません。 新しいコンテキスト上ではそのコンテキストを作ったオブジェクトと同じ方法で接続を立ち上げることができ、 その接続を同じ場所に格納しても元のコンテキストには何も影響を及ぼしません。

警告

print_r や var_dump などのオブジェクトのデバッグ用関数を実行するきには、 再帰の制限には含まれません。

注意:

リソース: PHP のリソースを定義している拡張モジュールは、この手の環境で扱うには不十分です。 pthreads はリソースをコンテキスト間で共有するための対策を用意していますが、 大半のリソース型は安全には扱えません。 コンテキスト間でリソースを共有するときには、いくら注意してもしすぎることはありません。

警告

pthreads の実行環境を安定させるには、いくつかの制限は必要になるのです。


pthreads
PHP Manual