Процесс зависает и ТРУБА заблокирована

Кажется, у меня тупик. У меня есть perl-скрипты разветвления и вызова других perl-скриптов. И процесс где-то зависает.

Я запускаю программу на:
Ядро Darwin Версия 12.3.0: Вс 6 января 22:37:10 PST 2013; root: xnu-2050.22.13 ~ 1 / RELEASE_X86_64 x86_64

«lsof» имеет 4 записи, относящиеся к одной и той же ТРУБЕ:

perl5.12 1414 root 1 ТРУБА 0x48937dc1254fe937 16384 -> 0x48937dc1254fe727

perl5.12 1768 root 1 ТРУБА 0x48937dc1254fe937 16384 -> 0x48937dc1254fe727

perl5.12 1759 root 1 ТРУБА 0x48937dc1254fe937 16384 -> 0x48937dc1254fe727

perl5.12 1760 root 1 ТРУБА 0x48937dc1254fe937 16384 -> 0x48937dc1254fe727

Я подозреваю, что это является причиной зависания.
Есть ли у нас какие-либо команды, которые могли бы сказать мне, какой процесс чтения / записи в эту ТРУБУ?
Или любая дополнительная информация будет оценена.
Заранее спасибо!

1

Решение

Есть две вероятные возможности, о которых я могу думать:

  1. Там тупик из-за буферизации вывода. Попробуйте включить автозапуск на всех выходных каналах. Это вероятно, если два процесса обмениваются данными в двух направлениях с использованием каналов: каждый из них что-то записывает и ожидает чтения ответа, но поскольку выходные данные буферизуются, ответ никогда не отправляется в канал.

  2. Процесс ожидает EOF на конвейере, но он никогда не приходит. Если канал создан в родительском процессе, а затем унаследован дочерним процессом, необходимо убедиться, что все процессы закрывают конец записи канала, чтобы читатель мог прочитать EOF.

0

Другие решения

Как объяснил Бармар, дочерние процессы могут застрять при заполнении выходного буфера. В этом случае вы обнаружите, что дочерний процесс застрял в write() Вызов функции.

Вам придется использовать Perl IO::Select Модуль в родительском процессе постоянно читает буфер вывода из дочернего процесса и, таким образом, очищает его, если выход дочернего процесса больше, чем буфер.

Официальная документация Perl на
http://perldoc.perl.org/functions/sysread.html
объясняет:

sysread FILEHANDLE, SCALAR, LENGTH
Попытки прочитать ДЛИННЫЕ байты данных
в переменную SCALAR из указанного FILEHANDLE, используя read (2). Это
обходит буферизованный ввод-вывод, поэтому смешивая это с другими видами чтения, печати,
писать, искать, рассказывать или что-либо еще может привести к путанице, потому что
Слои stdio обычно буферизуют данные.

Далее, чтобы увидеть Системную активность, я обычно использую strace Команда, которая хорошо показывает, как каждый процесс читает и записывает данные.

0