2010-12-15 3 views
3

Вот в чем проблема: У меня есть демон, который получает запросы от клиента, выполняет функцию (из некоторого модуля) из-за запроса и возвращает ответ на клиент. После того, как fork() закрою STDIN, STDOUT и STDERR. Одна функция - проверить dmesg. Для этого я получаю вывод dmesg через open (DMESG, "/ bin/dmesg |"). Я не закрываю этот fh после прочтения, потому что я думал, что он автоматически закрывается после завершения функции. Но этого не происходит, и я получаю зомби за каждый вызов dmesg.Perl: создание зомби через open() без закрытия()

How can I reinitialize Perl's STDIN/STDOUT/STDERR? Я обнаружил, что проблема с закрытием STDOUT вместо повторного открытия заключается в том, что если вы открываете другие файлы, они могут получить fd 0,1 или 2, что предотвратит повторное открытие STDOUT в будущем ». by jmanning2k И я думаю, что это как-то связано с этим, но я действительно не понимаю. Я надеюсь, что кто-то может объяснить это мне.

Я знаю, что могу избежать проблемы, например. вызывая dmesg через qx(); или просто закрывая fh, но я хочу понять, откуда берутся зомби.

ответ

6

Форма

open DMESG, "/bin/dmesg|"; 

открывает трубу и присваивает его к динамической области видимости переменнойDMESG. Динамически измененные переменные фактически живут «навсегда» в Perl, сохраняются при необходимости, когда видна local.

Если вы вместо того, чтобы использовать форму

open my $dmesg, "/bin/dmesg|"; 

лексического указатель_на_файл переменная $dmesg будет закрыта по размаху выходе, при условии, что нет никакой другой причины, чтобы сохранить его живым (т.е. он не передается обратно или иным образом хранится в глобальная переменная).

+0

Спасибо. thats это и thx для объяснения. – olo 2010-12-15 15:28:00

5

open(DMESG, "/bin/dmesg |") Я не закрыть после прочтения РД от него, потому что я думал, что она будет автоматически закрываться после функции завершена.

Для этого необходимо, чтобы ручка была лексической, поэтому она может попасть должным образом из сферы действия.

open my $dmesg, … 
+0

ahaha thats right. спасибо – olo 2010-12-15 15:26:41

1

Проблема связана с самим источником Perl. Вот часть кода из функции Perl_do_openn в файле doio.c:

fd = PerlIO_fileno(IoIFP(io)); 
if (IoTYPE(io) == IoTYPE_STD) { 
    /* This is a clone of one of STD* handles */ 
    result = 0; 
} 
else if (fd >= 0 && fd <= PL_maxsysfd) { 
    /* This is one of the original STD* handles */ 
    saveifp = IoIFP(io); 
    saveofp = IoOFP(io); 
    savetype = IoTYPE(io); 
    savefd = fd; 
    result = 0; 
} 

если открыть существующий дескриптор, то указатель_на_файл будет закрыт и вновь открытым способом(), Этого не происходит с ЗППП * обрабатывает, как вы можете видеть из приведенного выше кода. Таким образом, perl берет следующую свободную ручку для открытия, а старая остается открытой.

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