感謝のプログラミング 10000時間

たどり着いた結果(さき)は、感謝でした。

PHPでマルチスレッドプログラミングするために手元のCentOSにpthreadsをインストールして実際に動かしてみた

スポンサーリンク

昨日の記事のブコメで、id:hogegeさんから「非同期実行がいい感じでできるライブラリが欲しい」というコメントをいただいたので、
とりあえずPHPでマルチスレッド処理を実行しようと色々と調べてみた。

あんまりはてブつかないから、たまにコメントがあると嬉しいんだよね。
hogegeさん、ありがとうございます。

で、どうせならちゃんとした記事を書こうと思って、今日の仕事が終わって速攻で本屋に行ったんだけど、PHPでマルチスレッドプログラミングについて書かれているものは一冊もなかった。

・・・そりゃそうだ。
PHPはシングルスレッドで動くんだから(俺はPHP初心者なので、PHPRubyみたいに簡単にマルチスレッドが書けると思っていたのです)

でも、色々とネットで調べてみると、pthreadsというのを使えばPHPでもマルチスレッドが実現できるっぽい。
PHPでマルチスレッド
とはいえ、上のリンクにはインストールの仕方があまり書いてなくて、インストール段階で色々とつまづいたので、まずはpthreadsをインストールしてから動かすまでの過程を記述する。

・古いPHPパッケージをremoveする。

# yum erase php*

・epelをインストールする

rpm -Uvh http://mirrors.servercentral.net/fedora/epel/6/i386/epel-release-6-8.noarch.rpm

PHPをソースからインストールする準備

# cd /usr/src/
# wget -Ophp-5.5.1.tar.bz2 "http://us3.php.net/get/php-5.5.1.tar.bz2/from/this/mirror"
# tar jxf php-5.5.1.tar.bz2
# cd php-5.5.1

・ビルドに必要なツールをインストールする

# yum install gcc make install zlib-devel readline-devel libxml12-devel \
openssl-devel libmcrypt-devel curl-devel bzip2-devel xml2-config 

PHPをソースからビルドする

# ./configure --prefix=/usr --enable-maintainer-zts --with-pear \
> --with-config-file-path=/etc --with-readline --with-mcrypt \
> --with-zlib --enable-mbstring --with-curl --with-bz2 \
> --enable-zip --enable-sockets --enable-sysvsem --enable-sysvshm \
> --with-mhash --with-pcre-regex --with-gettext --enable-bcmath \
> --enable-libxml --enable-json --with-openssl --enable-pcntl


checking for grep that handles long lines and -e... /bin/grep

とすると、以下のようなエラーが発生した。

configure: error: xml2-config not found. Please check your libxml2 installation.

なので、libxml2-develをインストールした。

# yum install libxml2-devel

すると、ビルドが通った。

# make
# make install

peclを使ってpthreadsをインストールする

# pecl install channel://pecl.php.net/pthreads-0.0.44

Build process completed successfully
Installing '/usr/lib/php/extensions/no-debug-zts-20121212/pthreads.so'
install ok: channel://pecl.php.net/pthreads-0.0.44
configuration option "php_ini" is not set to php.ini location
You should add "extension=pthreads.so" to php.ini

最後に、php.iniに「extension=pthreads.so」を加えろって書いてあるから、書き加える。
その前に、php.iniの場所を調べる。
こんな感じのスクリプトを作って・・・

# cat phpinfo.php
----------------
#!/usr/bin/php
<?php
phpinfo();

実行。

# /usr/bin/php phpinfo.php  | grep php.ini
Configuration File (php.ini) Path => /etc

php.iniは/etcにあるらしい。

元々php.iniファイルはなかったので、

vi /etc/php.ini

で、ファイルを作って

extension=pthreads.so

を書き足した。

さてやーーーーっと準備ができたので、マルチスレッドプログラムを書いてみよう。
昨日と同じように、スクリプトで実行する。1行目はシバン。

#!/usr/bin/php

<?php
class MyThread extends Thread {
    function run() {
       echo "hoge",PHP_EOL;
    }
}

$thread = new MyThread();
$thread->start();

$thread2 = new MyThread();
$thread2->start();
?>	

これを実行すると・・・・

# /usr/bin/php threads.php

hoge
hoge

うおおお、やっとマルチスレッドっぽい(?)プログラムが動いた!
さて、次は並列でバッチファイルを動かすPHPプログラムを作ってみよう。
その前に風呂入る。

・結局一番参考になったページ
ほとんどこのページを見て真似した。
http://blog.slowbro.org/2013/08/compiling-php-55-with-pthreads-on-centos/
ここのページに辿り着くまで90分かかった。まじでありがとう。Thank you!

・参考にしたStackOverflow
http://stackoverflow.com/questions/16954113/installing-pthreads-in-windows
・サンプルがあるGithubはこちら。
krakjoe / pthreads

・Windows用のソースをダウンロードするならこちら
http://windows.php.net/downloads/pecl/releases/pthreads/

・ひっかかったエラー
pecl install pthreadsでインストールしようとしても、以下のエラーが出て使えなかった。

ERROR: `/tmp/pear/install/pthreads/configure' failed

・pthreadを使ってみたサンプル
pthreadsを使って、PHPからシェルスクリプトを非同期で並列に実行するサンプル