Re: поведение close на пайпе
- From
- Artem Chuprina (2:5020/400)
- To
- Denis Shaposhnikov
- Date
- 2005-07-12T12:11:30Z
- Area
- RU.PERL
From: Artem Chuprina <ran+news@ran.pp.ru>
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>> Но вообще как-то странно сформулирована задача. Если не
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. Но он его никогда не дождется,
DS> т.к. наш STDOUT туда же направлен и он не закрыть, следовательно для
DS> программы на том конце пайпа eof на STDIN не наступит. Правильно я
DS> понимаю?
Если тот конец завершается по eof на пайпе, то да. Подозреваю, что при
открытии в таком порядке закрывать имеет смысл в обратном - сперва
STDOUT, потом STDERR.
Artem>> непустой - см. выше. Тут, возможно, следует в какой-то
Artem>> ситуации сказать kill, чтобы он все-таки закрылся -
Artem>> файлхендлы-то вполне конкретные.
DS> Ага, вот с kill понятнее. Но надо же это сделать нежно. Т.е. 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)
SEEN-BY: 50/203 520 400/462 450/159 186 208 451/30 452/25 100 454/9 455/15
SEEN-BY: 461/33 43 74 106 132 640 464/34 465/204 467/24 469/125 200 999 478/44
SEEN-BY: 478/55 65 550/5004 5068 4600/126 4614/9 4616/3 4623/56 4625/8 9
SEEN-BY: 4626/100 4627/10 4632/10 4635/4 99 1024 4641/444 4642/27 48 4657/50
SEEN-BY: 5000/76 5001/50 5001 5002/76 5002 5003/34 5006/1 5007/1 5010/53 70
SEEN-BY: 5010/146 5011/13 5012/8 5015/4 28 214 5020/52 115 118 128 133 150 154
SEEN-BY: 5020/175 194 400 486 545 549 600 642 715 744 758 794 830 958 968 982
SEEN-BY: 5020/1057 1100 1169 1212 1234 1523 1604 1626 1642 1653 1665 1826 1829
SEEN-BY: 5020/1922 1930 2013 2020 2044 2142 2200 2238 2345 2590 2908 4400 4441
SEEN-BY: 5021/2 3 5022/128 5023/11 5024/1 73 5025/19 750 5026/14 49 5030/49 69
SEEN-BY: 5030/195 382 436 556 611 920 966 1016 1039 1063 1339 1520 1688 1900
SEEN-BY: 5031/7 47 63 70 5032/11 20 5033/35 5034/8 5035/3 38 63 5036/1 13
SEEN-BY: 5037/21 36 5038/4 5040/33 47 5041/4 5042/13 5045/7 42 5047/47 5049/1
SEEN-BY: 5049/6 157 5050/9 41 5051/15 35 5053/16 38 5054/1 8 9 35 36 37 45 50
SEEN-BY: 5054/66 67 81 85 5055/177 5056/16 5057/1 5058/77 5059/2 9 20 5060/88
SEEN-BY: 5060/90 5061/15 120 5062/1 4 7 36 5063/51 5064/7 35 39 5066/18
SEEN-BY: 5070/26 66 1222 5075/5 37 5077/70 80 5079/49 5080/80 1003 5081/2
SEEN-BY: 5082/6 5083/13 21 5090/23 105 108 113 5093/4 27 33 5096/18 5100/113
SEEN-BY: 6001/3 6023/1 6033/2727 6070/5
PATH: 5020/400 4441 52 5054/1 37