phpで並列処理する ライブラリを作った
TRANSCRIPT
![Page 1: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/1.jpg)
PHPで並列処理するライブラリを作った
ひろのぶ(@hironobu_s)
【2015/01/26】第86回 PHP勉強会
![Page 2: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/2.jpg)
自己紹介
• ひろのぶ(@hironobu_s)
• GMOインターネット株式会社テクニカルエバンジェリスト
• 自社サービスの企画、開発、インフラ運用をしてました
• 現在はConoHa (https://www.conoha.jp)を担当
![Page 4: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/4.jpg)
PHPで並列処理
![Page 5: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/5.jpg)
いろいろある
• バックグラウンドで実行する(php -f background.php 2>&1 /dev/null & のような)
• curl_multi系の関数を使う
• fork()する
• スレッドを使う(pthreadsとか)
![Page 6: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/6.jpg)
いろいろある
• バックグラウンドで実行する(php -f background.php 2>&1 /dev/null & のような)
• curl_multi系の関数を使う
• fork()する
• スレッドを使う(pthreadsとか)
←今回はこれを使う
![Page 7: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/7.jpg)
pcntl -プロセス制御関数
![Page 8: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/8.jpg)
プロセス制御関数
• pcntl_で始まる関数群
• Unix形式のプロセスを扱える
• Windows不可
![Page 9: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/9.jpg)
親プロセスと子プロセス
• プロセスとはプログラムの実行単位(phpコマンドなど)
• プロセスは自分自身の複製を作れる
• 作った側「親プロセス」、作られた側「子プロセス」
• PHPではpcntl_fork()を使う
![Page 10: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/10.jpg)
ParallelFor
• 拙作のライブラリです
• 配列の対するループ処理を並列化できる
• https://github.com/hironobu-s/parallel-for
![Page 11: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/11.jpg)
例
<?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);
![Page 12: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/12.jpg)
ちょうど5秒かかった
![Page 13: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/13.jpg)
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);
var_dump($data);
![Page 14: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/14.jpg)
0.78秒で終わった
![Page 15: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/15.jpg)
\はやい/
![Page 16: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/16.jpg)
何が起きてるの?
• 配列の要素数が50、一つ処理するのに100msというプログラム
• 一つずつ処理すると 100ms * 50 = 5,000ms = 5sec
• ParallelForは並列処理する(今回は並列数8で実行)
• 5000ms / 8 = 625ms だけど今回は782msだった
![Page 17: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/17.jpg)
図で見てみる(イメージです。実際はちょっと違います)
![Page 18: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/18.jpg)
![Page 19: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/19.jpg)
array_slice()
![Page 20: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/20.jpg)
![Page 21: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/21.jpg)
![Page 22: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/22.jpg)
![Page 23: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/23.jpg)
制約
• Windowsでは動かない(pcntlが使えない)
• mod_phpでは動かない(同上)
• リソース型を扱えない(Segfaultする)
![Page 24: PHPで並列処理する ライブラリを作った](https://reader034.vdocuments.site/reader034/viewer/2022042507/55a894a51a28ab1c608b48c6/html5/thumbnails/24.jpg)
おわり
• Github
https://github.com/hironobu-s/parallel-for
• Qiitahttp://qiita.com/hironobu_s/items/b72cb9d876e467c59697
ご清聴ありがとうございました