|
|
ru.perl- RU.PERL ---------------------------------------------------------------------- From : Denis Shaposhnikov 2:550/5068 12 Jul 2005 10:56:22 To : Artem Chuprina Subject : Re: поведение close на пайпе -------------------------------------------------------------------------------- >>>>> "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. Пробывал. Делаю свой обработчки CHLD, где в цикле waitpid с WNOHANG. Теперь в цикле выполняю close($fh), а потом вышеописанный open. По отладочному выводу вижу, что две итерации выполняются и мой обработчки вызывается, а на третий упс, висим в wait статусе и мой обработчки даже не вызвался. Висим именно на close. При этом, на том конце пайпа либо никого нет уже, либо там висят в состоянии pipewr. Я понимаю, что там заблокировались на записи, но мне этот пайп уже не нужен. Я хочу закрыть его нафиг и что бы на том конце получили SIGPIPE и успокоились. Artem> Hо вообще как-то странно сформулирована задача. Если не Artem> захочет завершиться, зачем close? Если б ты сказал, что он Artem> может сделать это не сразу, я б еще поверил... И не сразу в том числе. Проблема в том, что если происходит где-то die, то управление передается вверх, за пределы видимости. И $fh тогда уничтожается, а следовательно пытается закрыться. И не может. В итоге, программа висит на этом close вечно. 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); Вот по поводу этой конструкции. Сейчас опишу, как я понимаю из-за чего виснет close. Пайп у нас уже запущен. Мы пытаемся закрыть STDERR и close ждет завершения того конца pipe. Hо он его никогда не дождется, т.к. наш STDOUT туда же направлен и он не закрыть, следовательно для программы на том конце пайпа eof на STDIN не наступит. Правильно я понимаю? Artem> непустой - см. выше. Тут, возможно, следует в какой-то Artem> ситуации сказать kill, чтобы он все-таки закрылся - Artem> файлхендлы-то вполне конкретные. Ага, вот с kill понятнее. Hо надо же это сделать нежно. Т.е. TERM послать, потом подождать, потом KILL если не дождались. А как ждать, wait'ом с взведенным alarm? Может есть какой-нибудь модуль, где это уже реализовано? Artem> А вот на неявном flush с твоим STDOUT->autoflush(1) зависнуть Artem> у тебя есть все шансы. Почему? Разве мне не вернется SIGPIPE? -- DSS5-RIPE DSS-RIPN 2:550/5068@fidonet 2:550/5069@fidonet mailto:dsh@vlink.ru http://neva.vlink.ru/~dsh/ --- Gnus/5.1007 (Gnus v5.10.7) XEmacs/21.4.17 (Jumbo Shrimp, berkeley-unix) * Origin: Solar system, Jupiter (2:550/5068@fidonet) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.perl/77467e21a215.html, оценка из 5, голосов 10
|