へろへろもへじ

(ブログタイトル募集中)

【PHP】PHPBrewを利用してpthreadsを扱うための環境を作ってスレッドを動かしてみた

PHPでスレッドって使えるのかなぁとグーグル先生に聞いたところ、pthreadsなるものを利用すれば使えるらしいということがわかったのでちょろっと使ってみました。環境作るのがちょっとめんどくさかったので、備忘録としてメモ。

pthreadsってなんぞや?

PHPでスレッドを扱うためのモジュール

PHP: pthreads - Manual

PHPBrewってなんぞや?

異なるバージョンのPHPを簡単に切り替えることができるツール

phpbrew/README.ja.md at master · c9s/phpbrew · GitHub

環境構築

私の環境

  • OSはMac OSX 10.9 Mavericks
  • Command Line Toolsをインストール済み
  • peclが使える環境である

libmcryptをインストールする*1

1. 以下のサイトからダウンロード

http://sourceforge.net/projects/mcrypt/files/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz/download

2. 解凍して、インストールする

$ tar -zxvf libmcrypt-2.5.8.tar.gz
$ cd libmcrypt-2.5.8
$ ./configure
$ make
$ make install

PHPBrewをインストールする

1. PHPBrewをダウンロードする

$ curl -O https://raw.github.com/c9s/phpbrew/master/phpbrew
$ chmod +x phpbrew
$ sudo cp phpbrew /usr/bin/phpbrew

2. PHPBrewを設定する

$ phpbrew init
$ echo "source ~/.phpbrew/bashrc" >> ~/.bashrc
$ source ~/.bashrc

3. Zend Thread Safety(zts)を有効にしたPHPをインストールする*2

$ sudo phpbrew install php-5.5.9 +default -- --enable-maintainer-zts

4. インストールしたphp-5.5.9に切り替える

$ phpbrew use php-5.5.9

5. バージョンが切り替わったことを確認

$ php -v
PHP 5.5.9 (cli) (built: Mar  2 2014 18:24:11)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.5.0, Copyright (c) 1998-2014 Zend Technologies

pthreadsをインストールする*3

1. peclでpthreadsのエクステンションをインストールする

$ pecl install channel://pecl.php.net/pthreads-0.1.0

2. インストールされたことを確認する

$ php -m | grep pthreads
pthreads // ←表示されればインストールされている

3. php.iniにpthreadsの定義を追加する

$ vi ~/.phpbrew/php/php-5.5.9/etc/php.ini
--- 以下を追記
extension=pthreads.so

お試し

スレッドの動作を確認するために、以下のような簡単なサンプルコードを書いてみました。

仕様

  • 3スレッドを並列に動かす
  • 各スレッドは10回ループし、文字列を出力する
  • ループ毎にに1〜3秒ランダムでスリープする
<?php 

 class ThreadTest extends Thread 
 {
  public function __construct($str)
  {
    $this->str = $str;
  }

  public function run ()
  {
    foreach (range(1, 10) as $i) {
      echo "$i, $this->str" . PHP_EOL;
      sleep(rand(1,3));
    }

    echo "$this->str thread is finished" . PHP_EOL;
  }
}

$thread = new ThreadTest('hoge');
$thread2 = new ThreadTest('foo');
$thread3 = new ThreadTest('bar');

$thread->start();
$thread2->start();
$thread3->start();

実行

$ php pthread-sample.php
1, hoge
1, foo
1, bar
2, bar
2, foo
2, hoge
3, foo
3, bar
4, foo
3, hoge
4, bar
4, hoge
5, foo
6, foo
5, hoge
5, bar
7, foo
8, foo
6, hoge
6, bar
7, bar
9, foo
7, hoge
8, hoge
8, bar
10, foo
9, hoge
10, hoge
9, bar
foo thread is finished
10, bar
bar thread is finished
hoge thread is finished

おぉー。並列に動いてますね!これ使って何をするかは置いといてとりあえずは満足。
まだ使っていないWorkerとかStackableとかの使い方は下記の方のサンプルが参考になりそう。
krakjoe/pthreads · GitHub

*1:私の環境には入ってなかったのでコンパイラに怒られました

*2:Zend Thread Safety(zts)を有効にしないとpthredsが動きません

*3:インストールできるバージョンはこちらで確認(PECL :: Package :: pthreads