Главная страница


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)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 Re: поведение close на пайпе   Denis Shaposhnikov   12 Jul 2005 10:56:22 
Архивное /ru.perl/77467e21a215.html, оценка 1 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional