Symfony2 Process コンポーネントを使用して、プロセスのプールを手動で管理しています。
以下の例では、2 秒ごとに 2 つの単純なプロセスを再起動し、何が起こるかを監視します。これらのプロセスを数百回再起動すると、アプリケーションが壊れます。
実行が停止し、次の PHP 警告が表示されます。
proc_open(): unable to create pipe Too many open files
そして、次の例外が Symfony Process コンポーネントによってスローされます:
[Symfony\Component\Process\Exception\RuntimeException]
Unable to launch a new process.
開いているプロセスの総数を手動で監視しましたが、予想される制限を超えることはありません。
以下の簡略化されたスニペットは Symfony2 コマンドの一部であり、CLI から実行されています (例: app/console hamster:run):
$processes[] = new Process("ls > /dev/null", null, null, null, 2);
$processes[] = new Process("date > /dev/null", null, null, null, 2);
while (count($processes) > 0) {
foreach ($processes as $i => $process) {
if (!$process->isStarted()) {
$process->start();
continue;
}
try {
$process->checkTimeout();
} catch (\Exception $e) {
// Don't stop main thread execution
}
if (!$process->isRunning()) {
// All processes are timed out after 2 seconds and restarted afterwards
$process->restart();
}
}
usleep($sleep * 1000000);
}
このアプリケーションは、OS X 10.8.4 を実行している MAC サーバーで実行されています。
この問題の根本を追求する方法についてのヒントをいただければ幸いです。
更新 #1:関数を単純化して、次のような基本的なコマンドで動作するようls
にしdate
、テストを高速化しました。約 1000 ~ 1500 のプロセスを開始および停止した後でも、Process コマンドが失敗したように見えます。
各プロセスで正しく呼び出されていないのではないかと疑っていproc_close()
ましたが、さらに調査したところ、そうではないことがわかりました。