LINUX.ORG.RU

Perl: проблема повторного использования файлового дескриптора.


0

0

Заметил очень странное поведение нижеприведенной простейшей программы на Perl. По всем законам, программа должна вывести на стандартный вывод строку 'Hello!Hello2!Hello3!', затем после 5 секунд завершить выполнение. Однако все происходит с точности до наоборот: сначала программа ждет 5 секунд, потом выводит строку и завершает выполнение.

Замечено, что это связано с повторным использованием файлового дескриптора, хотя последний никак не связан с дескриптором STDOUT. Сами файлы в open() могут быть любыми, режим открытия тоже не влияет на результат. Если убрать строки с повторным использованием дескриптора FILE_D, то все начинает работать как надо.

Кто-нибудь может прокомментировать столь необычное поведение? Спасибо.

Собственно, исходник программы:

#!/usr/bin/perl -w

use strict; use locale;

open (FILE_D, '/etc/profile') or die("fail\n"); close (FILE_D);

open (FILE_D, '/etc/passwd') or die("fail\n");

tstprint();

close (FILE_D);

sub tstprint { print "Hello!"; print "Hello2!"; print "Hello3!"; sleep(5); }

Ответ на: комментарий от Die-Hard

Да, действительно, если добавить конец строки, или сбросить буффер, то все работает как надо. Но, даже если не применять эти меры, а просто убрать строки, повторно использующие дескриптор FILE_D, то есть:

open (FILE_D, '/etc/passwd') or die("fail\n");

то все начинает работать и без конца строки, либо сброса буффера.

Просто непонятно, почему так происходит? Может я чего-то не знаю?

nartamonov
() автор топика

> Заметил очень странное поведение нижеприведенной простейшей программы
> на Perl. По всем законам, программа должна вывести на стандартный
>вывод строку 'Hello!Hello2!Hello3!', затем после 5 секунд завершить
>выполнение.
>

Может грубовато, но ничего кроме "Авотх#й!" сказать не могу.

Вывод при помощи print - это вывод через stdio. С буферизацией.
Так как ты печатешь на терминал, по умолчанию буферизация по строкам.
Пока ты не напечатаешь "\n" никакого вывода не будет (ну или пока
буфер не заполнится). Естественно, проспав 5 секунд процесс
завершается и в процессе закрытия file handles происходит вывод
того, что еще осталось в буфере.

Отключить буферизацию можно, смотри perldoc perlvar на предмет
переменной $|, а также perldoc -q buffer

HTH

Onanim
()
Ответ на: комментарий от nartamonov

nartamonov:

> Просто непонятно, почему так происходит?

Буферизация -- интимное дело Перла. Он не обязан тебе гарантировать, когда ему буфера выталкивать.

Он обязан вытолкнуть линейный буфер при завершении строки. Он это делает. Почему при определенных условиях он флашает буфер с незавершенной строкой -- его внутреннее дело.

Die-Hard ★★★★★
()

Понял. Всем большое спасибо!

nartamonov
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.