MacOS X中产生的进程限制

MacOS X中产生的进程限制,macos,device,kqueue,Macos,Device,Kqueue,我在MacOS X Mountain Lion下遇到了一个引发大量进程(200个)的问题(尽管我确信这个问题不是特定于版本的)。我正在做的是启动进程(在我的测试中是/bin/cat),这些进程的STDIN、STDOUT和STDERR连接到管道——另一端是生成(父)进程 父进程将数据写入进程的STDIN,该STDIN通过管道传输到[/bin/cat]子进程,然后子进程将数据从STDOUT中吐出,并由父进程读取/bin/cat仅用于测试 实际上,我使用kqueue来通知STDIN管道中是否有可用空间

我在MacOS X Mountain Lion下遇到了一个引发大量进程(200个)的问题(尽管我确信这个问题不是特定于版本的)。我正在做的是启动进程(在我的测试中是/bin/cat),这些进程的STDIN、STDOUT和STDERR连接到管道——另一端是生成(父)进程

父进程将数据写入进程的STDIN,该STDIN通过管道传输到[/bin/cat]子进程,然后子进程将数据从STDOUT中吐出,并由父进程读取/bin/cat仅用于测试

实际上,我使用kqueue来通知STDIN管道中是否有可用空间。当kqueue通过EVFILT_WRITE事件通知您空间可用时,该事件还会准确地告诉您可以在不阻塞的情况下写入多少字节

这一切都很好,我可以很容易地生成100个子(/bin/cat)进程,所有的东西都在管道中流动而不会阻塞(一整天)。但是,当我将进程数增加到200时,当单个kqueue服务线程阻塞对其中一个STDIN管道的write()调用时,所有进程都会停止。该事件表示有16384字节可用(基本上是一个空管道),但当程序尝试将16384字节准确写入管道时,write()仍会阻塞

起初我以为我遇到了max.openfiles问题,但我将ulimit for open files提升到了8192,所以这不是问题所在。我在谷歌上发现,在OSX上,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实际上是设备的概念,我正在遇到某种限制


有人知道我遇到了什么限制吗?例如,可以创建的“设备”的数量有限制吗?这能增加多少吗?

回答我自己的问题。这似乎与MacOS X如何将管道从16K动态扩展到32K,再扩展到64K有关(以此类推)。我的基本解决方法是防止管道膨胀。看起来,只要你完全填满管道,操作系统就会将其展开。因此,当kqueue触发我可以写入管道,并指示我有16384个字节可供写入时,我只需写入16384-1个字节。基本上,无论它告诉我有多少可用字节,我最多写(可用-1)字节。这可以防止管道扩展,并防止我的代码遇到管道的write()会阻塞的情况(即使管道是非阻塞的)