2015-11-08 4 views
1

Из того, что я читал, fclose() в основном похож на free(), когда были выделены воспоминания, но я также прочитал, что операционная система закроет этот файл для вас и сбросит все потоки, открытые сразу после его завершения. Я даже тестировал несколько программ без fclose(), и все они работают нормально.Какой смысл fclose()?

+1

Что делать, если ваша программа работает много часов и хочет открыть и закрыть много файлов? У вас также не должно быть 'free()' memory, но если вы этого не сделаете, вы в конечном итоге исчерпали все ресурсы в какой-то момент. – 5gon12eder

+0

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

+0

Я видел более одного экземпляра, где дескриптор файла закрыт ОК, но ожидающие записи буферы НЕ сбрасываются, что приводит к файлам длиной 0, –

ответ

6

Долгосрочному процессу (например, базе данных или веб-браузеру) может потребоваться открыть много файлов за время его существования; сохраняя неиспользуемые файлы открытыми ресурсами отходов и потенциально блокируя другие процессы из-за использования файлов.

Кроме того, fclose очищает буфер пространства пользователя, который часто используется при записи в файлы для повышения производительности; если процесс завершается без промывки этого буфера (с fflush/fclose), данные, все еще находящиеся в буфере, будут потеряны.

1

Большинство современных операционных систем также восстанавливают память malloc() 'ed, но с использованием free(), когда это уместно, по-прежнему является хорошей практикой. Дело в том, что, как только вам больше не нужен ресурс, вы должны отказаться от него, поэтому система может перепрофилировать любые резервные ресурсы, которые были исправлены для использования другими приложениями (обычно, память). Также существуют ограничения на количество дескрипторов файлов, которые вы можете одновременно открывать.

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

Кроме того, семантика unlink() и друзья, что содержимое файла только «удалено» после того, как последний дескриптор открытого файла к файлу close() «d так снова: если вы храните файлы открытыми дольше, чем строго необходимо вызываешь субоптимальное поведение в общей системе.

И, наконец, в случае гнезд close() также соответствует разъединению от удаленного однорангового узла.

+0

Насколько я знаю, ни одна ОС не восстанавливает память malloc'd. Насколько я понимаю, ОС обычно даже не знает о malloc/free, поскольку они происходят исключительно внутри пользовательского пространства процесса. Даже с соответствующими вызовами ядра для выделения/освобождения страницы ядро ​​ОС будет восстанавливать только те страницы процесса, о которых конкретно говорит этот процесс. Он не будет пытаться самостоятельно восстановить страницы памяти. – Dreamer

+0

@Dreamer: ОС полностью осведомлена о том, какие страницы памяти в настоящее время утверждаются с помощью каких процессов. Если процесс умирает, AFAIK эти страницы не отображаются (если ни один другой процесс не использует те же самые), эффективно восстанавливая физическую память для будущего использования. Конечно, в реальном времени/встроенном пространстве есть много OS'ов, которые на самом деле не занимаются поисковой системой или виртуальной памятью. – user268396

+0

@ user268396 правильный.Любая нетривиальная ОС, безусловно, освободит любые страницы, которые больше не заявлены никаким процессом. Ядро не знает или не заботится о суб-распределителях, таких как malloc, только собственные данные о состоянии диспетчера виртуальной памяти. Когда процесс завершается, ОС может и будет останавливать все свои потоки, а затем освобождать все страницы памяти и другие ресурсы, которые не используются совместно. Если этого не произошло, «kill-9» и «End Process» диспетчера задач будут в лучшем случае неэффективными. –

Смежные вопросы