PHPで並列プログラミング

2008年7月9日(水)
田中 宏昌

サンプルコードを改良する

 図1のサンプルコードには改良すべき点が多々ありますが、一番問題なのは、恐らく高負荷になると安定しないということです。

 「3.手分けして同時に処理」の段階で、「&」を付けることでmysqlコマンドをバックグラウンドで走らせています。しかしそのバックグラウンドのプロセスが、完全に親プロセスの手から離れてしまうため、何らかの原因で処理がうまく終わらないと、14行目の判定ルーティンを突破することができません。

 また、完全に手が離れてしまうがゆえに、14、15行目のように子プロセスの終了判定のために、短い間隔でファイルをチェックすることになり、無駄にリソースを消費します。

popenを使ったサンプル

 これを解消するために、popen関数を用います。これはコマンドを子プロセスとして実行させることができます。この関数自体は、ファイルと同様にプロセスの戻り値を取り扱えます。fread関数でその結果を取得することができます。

 図2のプログラムが、popenを用いてサンプルコードを改良したものです。

 図1のサンプルコードと、プログラムの構造はほぼ同じです。並列でクエリを実行する部分は、図1の9~12行目が図2の9~13行目になっています。また、計算が終了するまで待って、結果を集計する部分は、図1の14~17行目が図2の15~21行目に対応します。
 内容的な大きな違いは、クエリの結果を、ファイル渡しではなく、プロセスの出力としてパイプで渡している点です。これを可能にしているのが12行目のpopen関数および17行目のfread関数です。17行目では、プロセスの出力をパイプ経由で受け取っていますが、受け取るものができるまで待っていてくれます。このため、終了判定の煩わしさや、リソースへの負荷が減ります。

 18行目で子プロセスへのファイルポインタを閉じます。この関数は子プロセスを終了させるのではなく、子プロセスの結果にアクセスする経路(パイプ)を閉じるだけです。今回のクエリは、結果が単純な数値であることがわかりきっているので、各子プロセスが終了したかを判定する複雑なロジックを省略しています。

 実行してみると、図1のサンプルコードとまったく同じ結果が返ってくると思います。

株式会社メディカルアーキテクツ
株式会社メディカルアーキテクツ、共同経営者。NTTデータ、NTTデータ経営研究所(出向)にてITプロジェクトの企画や企業の戦略系コンサルティングを数多く経験。その後、外資系医療コンサルティング企業のCIOとして伝説のシステムを数多く作り上げ、2年前に起業。東京大学工学部航空宇宙工学科卒。http://www.mediarc.jp/

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています