|
|
ru.perl- RU.PERL ---------------------------------------------------------------------- From : Artem Chuprina 2:5020/400 12 Jul 2005 12:11:30 To : Denis Shaposhnikov Subject : Re: поведение close на пайпе -------------------------------------------------------------------------------- Denis Shaposhnikov -> Artem Chuprina @ Tue, 12 Jul 2005 09:56:22 +0400: >>>>>> "Artem" == Artem Chuprina <ran+news@ran.pp.ru> writes: DS>> open(my $fh, "-|", "tail", "-F", "/some/file"); DS>> Теперь не понятно, как правильно $fh закрыть. Если просто DS>> close($fh), то можно в результате оказаться заблокированным на DS>> wait. Т.к. close ждет окончания процесса. А кто сказал, что он DS>> захочет завершиться. Как же рекомендуется делать такие вещи? Artem>> open тебе возвращает pid. Сделай ему waitpid с WNOHANG. Если Artem>> закончился - зови close. DS> Пробывал. Делаю свой обработчки CHLD, где в цикле waitpid с DS> WNOHANG. Теперь в цикле выполняю close($fh), а потом вышеописанный DS> open. По отладочному выводу вижу, что две итерации выполняются и мой DS> обработчки вызывается, а на третий упс, висим в wait статусе и мой DS> обработчки даже не вызвался. Висим именно на close. При этом, на том DS> конце пайпа либо никого нет уже, либо там висят в состоянии pipewr. Я DS> понимаю, что там заблокировались на записи, но мне этот пайп уже не DS> нужен. Я хочу закрыть его нафиг и что бы на том конце получили SIGPIPE DS> и успокоились. А что еще ты делаешь в цикле? Просто мне не очень понятно, при чем тут обработчик. Ты же хочешь пайп закрыть? Что до "я хочу закрыть его нафиг", то тут, видимо, надо уходить на уровень sysopen. Чтобы пайп отдельно, wait отдельно. Artem>> Hо вообще как-то странно сформулирована задача. Если не Artem>> захочет завершиться, зачем close? Если б ты сказал, что он Artem>> может сделать это не сразу, я б еще поверил... DS> И не сразу в том числе. Проблема в том, что если происходит где-то DS> die, то управление передается вверх, за пределы видимости. И $fh тогда DS> уничтожается, а следовательно пытается закрыться. И не может. В итоге, DS> программа висит на этом close вечно. Ловить исключение ниже по вложенности, очевидно. eval {} после open. DS>> close(STDERR) or warn "can't close STDERR: $!"; my $stderr_pid = DS>> open(STDERR, "|-", @$logger); die "can't open pipe to DS>> \"$logger_prog\": $!" unless defined Artem>> $stderr_pid; DS>> STDERR->autoflush(1); DS>> close(STDOUT) or warn "can't close STDOUT: $!"; open( STDOUT, DS>> ">&STDERR" ) or die "can't reopen STDOUT to STDERR: $!"; DS>> STDOUT->autoflush(1); DS> Вот по поводу этой конструкции. Сейчас опишу, как я понимаю из-за чего DS> виснет close. Пайп у нас уже запущен. Мы пытаемся закрыть STDERR и DS> close ждет завершения того конца pipe. Hо он его никогда не дождется, DS> т.к. наш STDOUT туда же направлен и он не закрыть, следовательно для DS> программы на том конце пайпа eof на STDIN не наступит. Правильно я DS> понимаю? Если тот конец завершается по eof на пайпе, то да. Подозреваю, что при открытии в таком порядке закрывать имеет смысл в обратном - сперва STDOUT, потом STDERR. Artem>> непустой - см. выше. Тут, возможно, следует в какой-то Artem>> ситуации сказать kill, чтобы он все-таки закрылся - Artem>> файлхендлы-то вполне конкретные. DS> Ага, вот с kill понятнее. Hо надо же это сделать нежно. Т.е. TERM DS> послать, потом подождать, потом KILL если не дождались. А как ждать, DS> wait'ом с взведенным alarm? Может есть какой-нибудь модуль, где это DS> уже реализовано? Artem>> А вот на неявном flush с твоим STDOUT->autoflush(1) зависнуть Artem>> у тебя есть все шансы. DS> Почему? Разве мне не вернется SIGPIPE? Это если он закроется. А если он задумается - нет, так и будешь там висеть. -- Artem Chuprina RFC2822: <ran{}ran.pp.ru> Jabber: ran@jabber.ran.pp.ru Попрошу благородного дона не обобщать с утра пораньше! (С)энта --- ifmail v.2.15dev5.3 * Origin: Leninsky 45 home network (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.perl/25606eebdb39a.html, оценка из 5, голосов 10
|