MacOS X Mountain Lion で多数のプロセス (200) を生成する問題が発生しています (ただし、この問題はバージョン固有ではありません)。私がやっていることは、STDIN、STDOUT、および STDERR がパイプに接続されているプロセス (私のテストでは /bin/cat です) を起動することです。そのもう一方の端は生成 (親) プロセスです。
親プロセスはデータをプロセスの STDIN に書き込みます。これは [/bin/cat] 子プロセスにパイプされます。次に子プロセスはデータを STDOUT から吐き出し、親プロセスによって読み取られます。/bin/cat はテスト用です。
私は実際にkqueueを使用して、STDINパイプに利用可能なスペースがあるときに通知を受けています。kqueue が EVFILT_WRITE イベントでスペースが利用可能であることを通知すると、このイベントは、ブロックせずに書き込むことができる正確なバイト数も通知します。
これはすべてうまく機能し、100 個の子 (/bin/cat) プロセスを簡単に作成でき、すべてがブロックされることなく (終日) パイプを通過します。ただし、プロセス数を 200 に増やすと、STDIN パイプの 1 つへの write() 呼び出しで単一の kqueue サービス スレッドがブロックされると、すべてが停止します。このイベントは、16384 バイト (基本的に空のパイプ) が使用可能であることを示していますが、プログラムが正確に 16384 バイトをパイプに書き込もうとすると、とにかく write() がブロックされます。
最初、私はマックスに走っていると思った。開いているファイルの問題ですが、開いているファイルの ulimit を 8192 に引き上げたので、それは問題ではありません。いくつかのグーグルで発見したことは、OS X では、STDIN/STDOUT/STDERR は実際には「ファイル」(または「パイプ」) ではなく、実際にはデバイスであるということです。プロセスがハングした場合、コマンドラインで lsof を実行すると、ファイル システムを stat() できないという警告が表示されてハングします。
lsof: WARNING: can't stat() hfs file system /
Output information may be incomplete.
assuming "dev=1000008" from mount table
プロセスを強制終了するとすぐに、lsof が完了します。これは、STDIN/OUT/ERR が実際にはデバイスであり、何らかの制限に直面しているという概念を強化します。
たとえば、作成できる「デバイス」の数に制限はありますか? これを何とか増やせないか?