PHPでマルチスレッド

More than 5 years have passed since last update.

PHPは最近の他の言語とは違ってシングルスレッドなので、一回のリクエストで複数の処理を同時に実行したりといったことは通常はできません。

非同期処理はできず、常に上から順に処理を進めていきます。

どうしてもやりたいなら`php hoge.php &`などと別プロセスで動かすといった手段しかありませんでした。

http://d.hatena.ne.jp/milktea_cg7/20130529/1369821459

ところでなにやらpthreadsとかいうモジュールを見つけたので使ってみます。

http://www.php.net/manual/ja/book.pthreads.php

LinuxであればPECLからインストールしましょう。

Windowsではバイナリが落ちてたので拾ってきます。

http://pecl.php.net/package/pthreads

https://github.com/krakjoe/pthreads

php_pthreads.dllをエクステンションのディレクトリに、pthreadVC2.dllは環境変数Pathが通っているところに置きます。

そしてphp.iniに以下を記述して再起動。

extension=php_pthreads.dll

これでpthreadsが使用可能になります。

phpinfo()にpthreadsという項目が追加されるのを確認しましょう。

それではさっそく実行。

<?php

class TestThread extends Thread{
/**
* @Overide
* startしたときに呼ばれる
*/

public function run(){
// 時間のかかる処理
sleep(10);

// このスレッドのIDを確認
print($this->getThreadId());
// これを呼び出したスレッドのIDを確認
print($this->getCreatorId());
}
}

// TestThreadを別スレッドで起動
$testThread1 = new TestThread();
$testThread1->start();
$testThread2 = new TestThread();
$testThread2->start();
$testThread3 = new TestThread();
$testThread3->start();
$testThread4 = new TestThread();
$testThread4->start();
$testThread5 = new TestThread();
$testThread5->start();

10秒かかる処理が5個あるということで一見50秒かかりそうですが、実際は10秒で処理が完了します。

TestThread::start()は、TestThread::run()を呼び出しますが、その処理の終了を待たずにすぐに次に進みます。

これでスレッド処理が簡単に行えます。

<?php

class TestThread extends Thread{
public function run(){
sleep(10);
}
}

// TestThreadを起動
$testThread = new TestThread();
$testThread->start();

// Thread::run()がまだ走っているか → true
var_dump($testThread->isRunning());

// Thread::run()が終了するまで待機
$testThread->join();

// Thread::run()がまだ走っているか → false
var_dump($testThread->isRunning());

join()はスレッドが終了するまで待機してくれます。

これで並列処理なんかも簡単に書けるようになりましたね。

まあスレッドが必要になるような処理をPHPで書くなよという話ではありますが。