Когда вам нужно `END {закрыть STDOUT}` в Perl? - PullRequest
15 голосов
/ 12 июня 2011

В бройлерной плите tchrists я обнаружил это явное закрытие STDOUT в блоке END.

END { close STDOUT }

Я знаю END и закройте, но мне не хватает, зачем это нужно.

Когда вы начинаете поиск по этому поводу, вы можете найти в perlfaq8 следующее:

Например, вы можете использовать это, чтобы убедиться, что вашей программе фильтра удалось завершитьего вывод без заполнения диска:

END {
    close(STDOUT) || die "stdout close failed: $!";
}

и все равно не понимаю.: (

Может кто-нибудь объяснить (может быть, с некоторыми примерами кода):

  • почему и когда это необходимо
  • как и в каких случаях можномой perl фильтр заполняет диск и т. д.
  • когда что-то не так без него ...
  • и т. д. ??

Ответы [ 2 ]

15 голосов
/ 12 июня 2011

Многие системы реализуют «оптимистичные» файловые операции.Под этим я подразумеваю, что вызов, например, print, который должен добавить некоторые данные в файл, может успешно вернуться до того, как данные фактически будут записаны в файл, или даже до того, как на диске будет зарезервировано достаточно местауспешная запись.

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

Эта ошибка означает, что весь вывод, который, как вы думали, вы сохранили, на самом деле вообще не был сохранен (или частично сохранен).Если это было важно, ваша программа должна сообщить об ошибке (или попытаться исправить ситуацию, или ...).

Все это может произойти с дескриптором файла STDOUT, если он подключен к файлу,Например, если ваш скрипт выполняется как:

perl script.pl > output.txt

Если выводимые вами данные важны, и вам необходимо знать, действительно ли все они написаны правильно, вы можете использовать утверждение, которое вы цитировалиобнаружить проблему.Например, во втором фрагменте сценарий явно вызывает die, если close сообщает об ошибке; шаблон tchrist работает под use autodie, который автоматически вызывает die в случае сбоя close.

(Это не гарантирует, что данные постоянно хранятся на диске, хотя другие факторы приходятв игру, но это хорошая индикация ошибки, т. е. если это закрытие не удастся, вы знаете, у вас есть проблема.)

4 голосов
/ 12 июня 2011

Я полагаю, что Мат ошибается.

И у Perl, и у системы есть буферы.close вызывает Буферы Perl для сброса в систему.Это не обязательно приводит к тому, что буферы системы записываются на диск, как утверждал Мэт.Это то, что делает fsync.

Теперь это может произойти в любом случае при выходе, но вызов close дает вам возможность обработать любую ошибку, с которой он столкнулся, сбрасывая буферы.close сообщает о более ранних ошибках при попытках системы сбросить свои буферы на диск.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...