Почему open()
и close()
существуют в дизайне файловой системы Unix?
Может ли ОС просто обнаружить первый раз read()
или write()
была вызвана и делать то, open()
что обычно делает?
files
filesystems
architecture
api
user5977637
источник
источник
open()
существует. «Не могла ли ОС просто обнаружить первый раз read () или write () и сделать то, что обычно делает open ()?» Есть ли соответствующее предложение для закрытия ?read()
илиwrite()
какой файл для доступа? Предположительно, пройдя путь. Что если путь к файлу изменится, когда вы к нему обращаетесь (между двумяread()
илиwrite()
вызовами)?read()
иwrite()
просто включеннымopen()
.Ответы:
Деннис Ритчи упоминает в «Эволюции Unix время обмена системы» , что
open
иclose
вместе сread
,write
иcreat
присутствовали в правой системе с самого начала.Я думаю, что система без
open
иclose
не будет немыслимой, однако я считаю, что это усложнит дизайн. Как правило, вы хотите сделать несколько вызовов чтения и записи, а не только один, и это, вероятно, было особенно верно на тех старых компьютерах с очень ограниченным объемом оперативной памяти, на которых возникла UNIX. Наличие дескриптора, который поддерживает текущее положение файла, упрощает это. Еслиread
илиwrite
должны были вернуть дескриптор, они должны были бы вернуть пару - дескриптор и их собственный статус возврата. Часть ручки пары была бы бесполезна для всех других вызовов, что сделало бы это расположение неловким. Выход из состояния курсора на ядро позволяет повысить эффективность не только за счет буферизации. Существует также некоторая стоимость, связанная с поиском пути - наличие дескриптора позволяет заплатить его только один раз. Кроме того, некоторые файлы в мировоззрении UNIX даже не имеют пути к файловой системе (или не имеют - теперь они делают с такими вещами, как/proc/self/fd
).источник
open
/close
, вы наверняка захотите реализовать такие вещи, как/dev/stdout
разрешить трубопровод.open()
вget_inode()
и сделал всю систему более жесткой (невозможно читать / писать один и тот же файл в нескольких позициях одновременно).Тогда все из
read
иwrite
вызовы должны передавать эту информацию по каждой операции:Считаете ли вы независимые вызовы
open
,read
,write
иclose
быть проще , чем одноцелевой I / O сообщение основано на вашей философии дизайна. Разработчики Unix решили использовать простые операции и программы, которые можно комбинировать разными способами, а не одну операцию (или программу), которая делает все.источник
read
иwrite
не ограничиваются файлами, которые живут в файловой системе, и это фундаментальное решение для разработки в Unix, как объясняет pjc50.lseek
)Концепция дескриптора файла важна из-за выбора дизайна UNIX, что «все является файлом», включая вещи, которые не являются частью файловой системы. Такие как ленточные накопители, клавиатура и экран (или телетайп!), Перфорированные устройства чтения карт / лент, последовательные соединения, сетевые соединения и (ключевое изобретение UNIX) прямые соединения с другими программами, называемыми «каналами».
Если вы посмотрите на многие из простого стандартного UNIX утилита типа
grep
, особенно в их оригинальной версии, вы заметите , что они не включают в себя вызовы кopen()
и ,close()
но толькоread
иwrite
. Дескрипторы файла устанавливаются оболочкой вне программы и передаются при запуске. Поэтому программе не нужно заботиться о том, записывает ли она файл или другую программу.А также
open
, другие способы получения файлов дескрипторыsocket
,listen
,pipe
,dup
, и очень Heath Robinson механизм для передачи дескрипторов файлов через трубу: https://stackoverflow.com/questions/28003921/sending-file-descriptor-by-linux -разъемИзменить: некоторые лекционные заметки, описывающие слои косвенности и как это позволяет O_APPEND работать разумно. Обратите внимание, что хранение данных inode в памяти гарантирует, что системе не придется идти и извлекать их снова для следующей операции записи.
источник
creat
, иlisten
не создает fd, но когда (и если) поступает запрос во время прослушивания,accept
создается и возвращается fd для нового (подключенного) сокета.pipe
был представлен через несколько лет после начала разработки под Unix.Ответ - нет, потому что open () и close () создают и уничтожают дескриптор соответственно. Есть моменты (ну, действительно, все время, действительно), когда вы можете захотеть гарантировать, что вы являетесь единственным вызывающим абонентом с определенным уровнем доступа, так как другой вызывающий (например) записывающий файл, который вы анализируете, неожиданно может оставить приложение в неизвестном состоянии или приводящее к живому или тупиковому состоянию, например, лемма «Обедающие философы».
Даже без этого соображения есть последствия для производительности, которые следует учитывать; close () позволяет файловой системе (если это уместно или если вы вызвали ее) очистить буфер, который вы занимали, дорогая операция. Несколько последовательных изменений в потоке в памяти гораздо эффективнее, чем несколько по существу не связанных циклов чтения-записи-изменения в файловой системе, которая, как вы знаете, существует на расстоянии полмира, разбросанная по центру обработки данных с большой задержкой. Даже при локальном хранении память обычно на много порядков быстрее, чем объемное хранилище.
источник
Open () предлагает способ блокировки файлов во время их использования. Если файлы были автоматически открыты, прочитаны / записаны, а затем снова закрыты ОС, ничто не помешает другим приложениям изменять эти файлы между операциями.
Хотя это может быть управляемым (многие системы поддерживают неисключительный доступ к файлам) для простоты, большинство приложений предполагают, что открытые ими файлы не изменяются.
источник
Поскольку путь к файлу может двигаться, если вы предполагаете, что он останется прежним.
источник
Чтение и запись в файловую систему может включать в себя большое разнообразие схем буферизации, ведение операционной системы, низкоуровневое управление дисками и множество других возможных действий. Таким образом, действия
open()
иclose()
служат в качестве установки для этих видов деятельности под капотом. Различные реализации файловой системы могут быть сильно настроены по мере необходимости и при этом оставаться прозрачными для вызывающей программы.Если в ОС не было открытия / закрытия, то с помощью
read
илиwrite
эти действия с файлами все равно должны были бы выполнять инициализацию, очистку буфера / управление и т. Д. Каждый раз. Это много накладных расходов для повторного чтения и записи.источник
Unix-мантра - это «предлагать один способ ведения дел», что означает «разложение» на (повторно используемые) кусочки, которые можно объединять по желанию. Т.е. в этом случае отделите создание и уничтожение файловых дескрипторов от их использования. Важные преимущества появились позже, с каналами и сетевыми подключениями (ими также манипулируют с помощью файловых дескрипторов, но они создаются другими способами). Возможность доставки файловых дескрипторов (например, передача их дочерним процессам в виде «открытых файлов», которые выживают
exec(2)
и даже несвязанным процессам через канал) возможна только таким способом. Особенно, если вы хотите предложить контролируемый доступ к защищенному файлу. Таким образом, вы можете, например, открыть/etc/passwd
для записи и передачи его дочернему процессу, которому не разрешено открывать этот файл для записи (да, я знаю, что это нелепый пример, не стесняйтесь редактировать что-то более реалистичное).источник