2013-09-11 4 views
0

Я столкнулся с проблемой, порождающей большое количество процессов (200) под MacOS X Mountain Lion (хотя я уверен, что эта проблема не зависит от версии). То, что я делаю, - это запуск процессов (в моем тесте это/bin/cat), которые имеют STDIN, STDOUT и STDERR, подключенные к трубам, другим концом которых является процесс нереста (родителя).Установленный предел процесса в MacOS X

Родительский процесс записывает данные в STDIN процессов, которые передаются по каналам дочерних процессов [/ bin/cat], которые, в свою очередь, вытесняют данные из STDOUT и считываются родительским процессом./bin/cat используется только для тестирования.

Я использую kqueue для уведомления, когда в трубе STDIN есть место. Когда kqueue уведомляет вас о событии EVFILT_WRITE, которое доступно, событие также сообщает вам, сколько байтов можно записать без блокировки.

Все это работает хорошо, и я могу легко создать 100 дочерних (/ bin/cat) процессов, и все течет через трубы без блокировки (весь день). Однако, когда я запускаю количество процессов до 200, все останавливается, когда один поток обслуживания kqueue блокируется при вызове write() на один из STDIN-каналов. Событие говорит, что имеется 16384 байт (в основном пустой пул), но когда программа пытается записать ровно 16384 байт в канал, блоки write() в любом случае.

Первоначально я думал, что столкнулся с максимумом. проблема с открытыми файлами, но я поднял ulimit для открытых файлов до 8192, так что это не проблема. То, что я обнаружил из какого-то googling, это то, что в OS X STDIN/STDOUT/STDERR на самом деле не являются «файлами» (или «трубами»), а фактически являются устройствами. Когда процесс завис, работает LSOF в командной строке также висит с предупреждением о не в состоянии стат() файловая система:

lsof: WARNING: can't stat() hfs file system/
     Output information may be incomplete. 
     assuming "dev=1000008" from mount table 

Как только я убить процесс, Lsof завершается. Это усиливает представление о том, что STDIN/OUT/ERR на самом деле являются устройствами, и я сталкиваюсь с каким-то ограничением.

Есть ли у кого-нибудь представление о том, какой предел я использую, например, существует ли ограничение на количество создаваемых «устройств»? Может ли это как-то быть увеличено?

ответ

0

Просто, чтобы ответить на мой собственный вопрос здесь. Это, как представляется, связано с тем, как MacOS X будет динамически расширять канал с 16K до 32K до 64K (и так далее). Мое основное решение заключалось в том, чтобы предотвратить расширение трубы. Похоже, что всякий раз, когда вы полностью заполняете трубку, ОС расширяет ее. Итак, когда kqueue запускает, что я могу записать в трубу, и указывает, что у меня есть 16384 байт, доступных для записи, я просто пишу 16384 - 1 байт. В принципе, независимо от того, что он говорит мне, я имею доступ, я пишу максимум (доступно - 1) байт. Это предотвращает расширение трубы и препятствует тому, чтобы мой код столкнулся с условием блокировки записи() в трубе (даже если труба не блокирует).

Смежные вопросы