PHPで並列処理する
ライブラリを作った
ひろのぶ(@hironobu_s)
【2015/01/26】第86回 PHP勉強会
自己紹介
• ひろのぶ(@hironobu_s)
• GMOインターネット株式会社
テクニカルエバンジェリスト
• 自社サービスの企画、開発、インフラ運用をしてました
• 現在はConoHa (https://www.conoha.jp)を担当
ConoHa
https://www.conoha.jp/conoha/
PHPで並列処理
いろいろある
• バックグラウンドで実行する
(php -f background.php 2>&1 /dev/null & のような)
• curl_multi系の関数を使う
• fork()する
• スレッドを使う(pthreadsとか)
いろいろある
• バックグラウンドで実行する
(php -f background.php 2>&1 /dev/null & のような)
• curl_multi系の関数を使う
• fork()する
• スレッドを使う(pthreadsとか)
←今回はこれを使う
pcntl - プロセス制御関数
プロセス制御関数
• pcntl_で始まる関数群
• Unix形式のプロセスを扱
える
• Windows不可
親プロセスと子プロセス
• プロセスとはプログラムの実行単位(phpコマンドなど)
• プロセスは自分自身の複製を作れる
• 作った側「親プロセス」、作られた側「子プロセス」
• PHPではpcntl_fork()を使う
ParallelFor
• 拙作のライブラリです
• 配列の対するループ処理を並列化できる
• https://github.com/hironobu-s/parallel-for
例
<?php
$data = [];
for($i = 0; $i < 50; $i++) {
$data[] = "data $i";
}
$result = [];
foreach($data as $data) {
usleep(100000); // 100msのウエイト
$result[] = $data . " processed.";
}
var_dump($result);
ちょうど5秒かかった
ParallelFor を使う<?php
require_once 'parallel-for/src/ParallelFor.php';
// 処理内容
$exec = function($datas) {
$result = [];
foreach($datas as $data) {
usleep(100000); // 100msのウエイト
$result[] = $data . " processed.";
}
return $result;
};
// テストデータの準備
$data = [];
for($i = 0; $i < 10; $i++) {
$data[] = "data $i";
}
// 実行
$p = new ParallelFor();
$p->setNumChilds(8);
$data = $p->run($data, $exec);
0.78秒で終わった
\ はやい/
何が起きてるの?
• 配列の要素数が50、一つ処理するのに100msというプロ
グラム
• 一つずつ処理すると 100ms * 50 = 5,000ms = 5sec
• ParallelForは並列処理する(今回は並列数8で実行)
• 5000ms / 8 = 625ms だけど今回は782msだった
図で見てみる
(イメージです。実際はちょっと違います)
array_slice()
制約
• Windowsでは動かない(pcntlが使えない)
• mod_phpでは動かない(同上)
• リソース型を扱えない(Segfaultする)
おわり
• Github
https://github.com/hironobu-s/parallel-for
• Qiita
http://qiita.com/hironobu_s/items/b72cb9d876e467c59697
ご清聴ありがとうございました

PHPで並列処理する ライブラリを作った