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

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

Я запускаю программу на: Darwin Kernel Версия 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

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

2 ответа

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

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

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

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

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

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

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

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

Другие вопросы по тегам