Блокировка файлов — это механизм, ограничивающий доступ к файлу на компьютере или к области файла, позволяя изменять или удалять его в определенное время только одному пользователю или процессу , а также предотвращающий чтение файла во время его изменения или удаления.
Системы реализуют блокировку для предотвращения классического сценария промежуточного обновления , который является типичным примером состояния гонки , путем принудительной сериализации процессов обновления для любого заданного файла. Следующий пример иллюстрирует проблему промежуточного обновления:
Большинство операционных систем поддерживают концепцию блокировки записей , что означает, что отдельные записи в любом заданном файле могут быть заблокированы, тем самым увеличивая количество одновременных процессов обновления. Обслуживание базы данных использует блокировку файлов, посредством чего оно может сериализовать доступ ко всему физическому файлу, лежащему в основе базы данных. Хотя это не позволяет любому другому процессу получить доступ к файлу, это может быть более эффективным, чем индивидуальная блокировка многих областей в файле, поскольку устраняет накладные расходы на получение и снятие каждой блокировки.
Неправильное использование блокировок файлов, как и любой блокировки компьютера , может привести к снижению производительности или к тупикам . Блокировка файлов может также относиться к дополнительной безопасности, применяемой пользователем компьютера либо с помощью безопасности Windows, разрешений NTFS, либо путем установки стороннего программного обеспечения для блокировки файлов.
IBM впервые применила блокировку файлов в 1963 году для использования в мэйнфреймах с использованием OS/360 , где она называлась «исключительным контролем». [1]
Microsoft Windows использует три различных механизма для управления доступом к общим файлам:
Windows наследует семантику управления общим доступом из системы MS-DOS , где общий доступ был введен в MS-DOS 3.3. Таким образом, приложение должно явно разрешать общий доступ при открытии файла; в противном случае оно имеет исключительный доступ на чтение, запись и удаление файла до его закрытия (другие типы доступа, например, для получения атрибутов файла, разрешены).
Для файла, открытого с общим доступом, приложения могут затем использовать блокировку байтового диапазона для управления доступом к определенным областям файла. Такие блокировки байтового диапазона определяют область файла (смещение и длину) и тип блокировки (общая или исключительная). Обратите внимание, что область блокируемого файла не обязательно должна иметь данные внутри файла, и приложения иногда используют эту возможность для реализации своей функциональности.
Для приложений, использующих API чтения/записи файлов в Windows, блокировки байтового диапазона принудительно применяются (также называются обязательными блокировками ) файловыми системами, которые выполняются в Windows. Для приложений, использующих API отображения файлов в Windows, блокировки байтового диапазона не применяются (также называются рекомендательными блокировками ). Блокировка байтового диапазона может также иметь другие побочные эффекты в системе Windows. Например, механизм обмена файлами Windows обычно отключает кэширование файла на стороне клиента для всех клиентов, когда блокировки байтового диапазона используются любым клиентом. Клиент будет наблюдать более медленный доступ, поскольку операции чтения и записи должны быть отправлены на сервер, где хранится файл.
Неправильная обработка ошибок в прикладной программе может привести к ситуации, когда файл заблокирован (используя либо доступ "share", либо блокировку файла по байтовому диапазону) и другие приложения не смогут получить к нему доступ. Если это так, пользователь может восстановить доступ к файлу, вручную завершив неисправную программу. Обычно это делается с помощью утилиты Task Manager .
Параметр режима общего доступа (dwShareMode) функции CreateFile
[2] (используется для открытия файлов) определяет общий доступ к файлу. Режим общего доступа может быть указан для разрешения общего доступа к файлу для чтения, записи или удаления или любой их комбинации. Последующие попытки открыть файл должны быть совместимы со всеми ранее предоставленными правами общего доступа к файлу. Когда файл закрывается, ограничения общего доступа корректируются для снятия ограничений, налагаемых открытием этого конкретного файла.
Тип блокировки диапазона байтов определяется параметром dwFlags
в функции LockFileEx
[4] , используемой для блокировки области файла. Также может использоваться функция Windows API LockFile
[5] , которая устанавливает исключительную блокировку на область файла.
Любой файл, содержащий исполняемый программный файл, который в данный момент выполняется в компьютерной системе как программа (например EXE
, , COM, DLL, CPLили другой двоичный формат файла программы), обычно блокируется самой операционной системой, не позволяя любому приложению изменять или удалять его. Любая попытка сделать это будет отклонена с ошибкой нарушения общего доступа, несмотря на то, что программный файл не открыт ни одним приложением. Однако некоторый доступ все еще разрешен. Например, запущенный файл приложения может быть переименован или скопирован (прочитан) даже во время выполнения.
Файлы доступны приложениям в Windows с помощью дескрипторов файлов . Эти дескрипторы файлов можно исследовать с помощью утилиты Process Explorer . Эту утилиту также можно использовать для принудительного закрытия дескрипторов без необходимости завершения приложения, удерживающего их. Это может привести к неопределенному поведению, поскольку программа получит непредвиденную ошибку при использовании принудительно закрытого дескриптора и может даже работать с неожиданным файлом, поскольку номер дескриптора может быть повторно использован. [ необходима цитата ]
В редакциях Microsoft Windows XP и Server 2003 появилась возможность моментального снимка тома ( VSS
) для NTFS , что позволяет программному обеспечению резервного копирования получать доступ к открытым файлам, несмотря на любые исключительные блокировки. Однако, если программное обеспечение не переписано специально для поддержки этой функции, моментальный снимок будет только аварийно-согласованным , в то время как правильно поддерживаемые приложения могут помочь операционной системе в создании «транзакционно-согласованных» моментальных снимков. Другое коммерческое программное обеспечение для доступа к заблокированным файлам в Windows включает File Access Manager и Open File Manager. Они работают, устанавливая собственные драйверы для доступа к файлам в режиме ядра .
Unix-подобные операционные системы (включая Linux и macOS от Apple ) обычно не блокируют автоматически открытые файлы. Несколько видов механизмов блокировки файлов доступны в различных вариантах Unix, и многие операционные системы поддерживают более одного вида для совместимости. Наиболее распространенным механизмом является . Двумя другими такими механизмами являются и
, каждый из которых может быть реализован поверх
fcntl
или отдельно от fcntl
. Хотя некоторые типы блокировок можно настроить как обязательные, блокировки файлов в Unix по умолчанию являются рекомендательными . Это означает, что сотрудничающие процессы могут использовать блокировки для координации доступа к файлу между собой, но несотрудничающие процессы также могут игнорировать блокировки и получать доступ к файлу любым выбранным ими способом. Другими словами, блокировки файлов блокируют только другие блокировщики файлов, но не ввод-вывод.
Предлагаются два вида блокировок: разделяемые блокировки и исключительные блокировки. В случае fcntl
различные виды блокировок могут применяться к различным разделам (байтовым диапазонам) файла или ко всему файлу. Разделяемые блокировки могут удерживаться несколькими процессами одновременно, но исключительная блокировка может удерживаться только одним процессом и не может сосуществовать с разделяемой блокировкой. Чтобы получить разделяемую блокировку, процесс должен ждать, пока ни один процесс не будет удерживать исключительные блокировки. Чтобы получить исключительную блокировку, процесс должен ждать, пока ни один процесс не будет удерживать ни один из видов блокировок. В отличие от блокировок, созданных fcntl
, те, которые созданы , flock
сохраняются между fork
s, что делает их полезными при разветвлении серверов. Поэтому возможно, чтобы более чем один процесс удерживал исключительную блокировку одного и того же файла, при условии, что эти процессы разделяют дочерние отношения, и исключительная блокировка была изначально создана в одном процессе, прежде чем была продублирована через fork
.
Разделяемые блокировки иногда называют «блокировками чтения», а исключительные блокировки иногда называют «блокировками записи». Однако, поскольку блокировки в Unix являются рекомендательными, это не применяется принудительно. Таким образом, для базы данных возможно иметь концепцию «разделяемых записей» против «исключительных записей»; например, изменение поля на месте может быть разрешено при общем доступе, тогда как сборка мусора и перезапись базы данных могут потребовать исключительного доступа.
Блокировки файлов применяются к фактическому файлу, а не к имени файла. Это важно, поскольку Unix позволяет нескольким именам ссылаться на один и тот же файл. Вместе с необязательной блокировкой это обеспечивает большую гибкость в доступе к файлам из нескольких процессов. С другой стороны, подход кооперативной блокировки может привести к проблемам, когда процесс записывает в файл, не подчиняясь блокировкам файлов, установленным другими процессами.
По этой причине некоторые операционные системы типа Unix также предлагают ограниченную поддержку обязательной блокировки . [6] В таких системах файл, setgid
бит которого включен, но бит группового выполнения которого выключен при открытии этого файла, будет подвергаться автоматической обязательной блокировке, если базовая файловая система поддерживает это. Однако нелокальные разделы NFS, как правило, игнорируют этот бит. [7] Если файл подлежит обязательной блокировке, попытки чтения из области, заблокированной исключительной блокировкой, или записи в область, заблокированную общей или исключительной блокировкой, будут блокироваться до тех пор, пока блокировка не будет снята. Эта стратегия впервые возникла в System V, и сегодня ее можно увидеть в операционных системах Solaris , HP-UX и Linux. Однако она не является частью POSIX, и операционные системы, производные от BSD, такие как FreeBSD , OpenBSD , NetBSD и macOS от Apple, не поддерживают ее. [8] Linux также поддерживает обязательную блокировку с помощью специального -o mand
параметра для монтирования файловой системы ( ), но это используется редко.
Некоторые Unix-подобные операционные системы предотвращают попытки открыть исполняемый файл работающей программы для записи; это третья форма блокировки, отличная от тех, которые предусмотрены fcntl
и flock
.
Более одного процесса могут удерживать эксклюзив flock
на данном файле, если эксклюзивная блокировка была продублирована в более позднем fork
. Это упрощает кодирование для сетевых серверов и помогает предотвратить состояния гонки, но может сбивать с толку неосведомленных.
Обязательные блокировки не оказывают никакого влияния на unlink
системный вызов. Следовательно, некоторые программы могут эффективно обходить обязательную блокировку. Стивенс и Раго (2005) заметили, что ed
редактор действительно это сделал. [9]
flock
Работают ли блокировки в сетевых файловых системах, таких как NFS , и как они работают , зависит от реализации. В системах BSDflock
вызовы файлового дескриптора, открытого для файла на смонтированном разделе NFS, являются успешными no-ops . В Linux до версии 2.6.12 flock
вызовы файлов NFS будут действовать только локально. Ядро 2.6.12 и выше реализует вызовы flock
файлов NFS с использованием блокировок байтового диапазона POSIX. Эти блокировки будут видны другим клиентам NFS, которые реализуют блокировки POSIXfcntl
в стиле , но невидимы для тех, которые этого не делают. [10]
Обновления и понижения блокировки снимают старую блокировку перед применением новой блокировки. Если приложение понижает исключительную блокировку до общей блокировки, пока другое приложение заблокировано в ожидании исключительной блокировки, последнее приложение может получить исключительную блокировку и заблокировать первое приложение. Это означает, что понижения блокировки могут блокировать, что может быть нелогично.
Все fcntl
блокировки, связанные с файлом для данного процесса, удаляются, когда любой файловый дескриптор для этого файла закрывается этим процессом, даже если блокировка никогда не запрашивалась для этого файлового дескриптора. Кроме того, fcntl
блокировки не наследуются дочерним процессом. fcntl
Семантика закрытия особенно проблематична для приложений, которые вызывают библиотеки подпрограмм, которые могут получать доступ к файлам. Ни одна из этих "ошибок" не происходит при использовании настоящих flock
блокировок в стиле.
Сохранение статуса блокировки открытых файловых дескрипторов, переданных другому процессу с использованием сокета домена Unix, зависит от реализации.
Один из источников сбоя блокировки возникает, когда буферизованный ввод-вывод имеет буферы, назначенные в локальной рабочей области пользователя, а не в пуле буферов операционной системы. fread
и fwrite
обычно используются для буферизованного ввода-вывода, и как только раздел файла прочитан, другая попытка прочитать тот же раздел, скорее всего, получит данные из локального буфера. Проблема в том, что другой пользователь, подключенный к тому же файлу, имеет свои собственные локальные буферы, и для них происходит то же самое. fwrite
Полученные из буфера данные неfread
будут получать данные из самого файла, и какой-то другой пользователь мог изменить их. Оба могут использовать для обеспечения исключительного доступа, что предотвращает одновременную запись, но поскольку чтение считывается из буфера, а не из самого файла, любые данные, измененные пользователем № 1, могут быть потеряны пользователем № 2 (перезаписаны). Лучшим решением этой проблемы является использование небуферизованного ввода-вывода ( и ) с , что также означает использование вместо и . Конечно, вам придется внести корректировки в параметры функции и возвращаемые результаты. Вообще говоря, буферизованный ввод-вывод небезопасен при использовании с общими файлами.flock
read
write
flock
lseek
fseek
ftell
В AmigaOS блокировка файла (или каталога) может быть получена с помощью Lock
функции (в dos.library
). Блокировка может быть общей (другие процессы могут читать файл/каталог, но не могут изменять или удалять его) или исключительной, так что только процесс, успешно получивший блокировку, может получить доступ или изменить объект. Блокировка распространяется на весь объект, а не на его часть. Блокировка должна быть снята с помощью UnLock
функции: в отличие от Unix, операционная система неявно разблокирует объект при завершении процесса.
Скрипты оболочки и другие программы часто используют стратегию, похожую на использование блокировки файлов: создание файлов блокировки , которые представляют собой файлы, содержимое которых не имеет значения (хотя часто можно найти идентификатор процесса держателя блокировки в файле) и чьей единственной целью является сигнализировать своим присутствием, что какой-то ресурс заблокирован. Файл блокировки часто является наилучшим подходом, если ресурс, который нужно контролировать, вообще не является обычным файлом, поэтому использование методов блокировки файлов не применимо. Например, файл блокировки может управлять доступом к набору связанных ресурсов, таким как несколько различных файлов, каталогов, группа разделов диска или выбранный доступ к протоколам более высокого уровня, таким как серверы или соединения с базами данных.
При использовании файлов блокировки необходимо позаботиться о том, чтобы операции были атомарными . Чтобы получить блокировку, процесс должен проверить, что файл блокировки не существует, а затем создать его, не допуская при этом создания его другим процессом. Различные методы для этого включают:
lockfile
команду (условный создатель семафорных файлов, входящий в procmail
пакет).mkdir
команды и проверка кода выхода на предмет сбоя [11]Файлы блокировки часто именуются с тильдой ( ~
) в качестве префикса к имени файла, который они блокируют, или дубликатом полного имени файла с суффиксом .LCK
. Если они блокируют ресурс, отличный от файла, они могут быть названы более произвольно.
Unlocker — это утилита, используемая для определения того, какой процесс блокирует файл, и отображающая список процессов, а также варианты действий с процессом (kill task, unlock и т. д.) вместе со списком параметров файлов, таких как удаление или переименование. Их цель — удалить неправильные или устаревшие блокировки файлов, которые часто возникают из-за аномальных ситуаций, таких как аварийно завершившиеся или зависшие процессы, которые приводят к блокировкам файлов, которые сохраняются, несмотря на то, что владеющий процесс уже умер. В некоторых Unix-подобных системах такие утилиты, как fstat
и lockf
могут использоваться для проверки состояния блокировок файлов по процессу, по имени файла или по обоим параметрам. [ необходима цитата ]
В системах Windows, если файл заблокирован, можно запланировать его перемещение или удаление на следующую перезагрузку. Такой подход обычно используется установщиками для замены заблокированных системных файлов.
В системах контроля версий блокировка файлов используется для предотвращения изменения двумя пользователями одной и той же версии файла параллельно, а затем при сохранении, чтобы второй пользователь перезаписал то, что изменил первый пользователь. Это реализуется путем пометки заблокированных файлов как доступных только для чтения в файловой системе. Пользователь, желающий изменить файл, выполняет операцию разблокировки (также называемую извлечением), и пока не будет выполнена операция регистрации (сохранения) или блокировка не будет отменена, никто другой не сможет разблокировать файл.
Поддержка обязательных блокировок сильно различается в зависимости от варианта Unix. Linux и Solaris поддерживают обязательные блокировки, но Darwin , FreeBSD , NetBSD и OpenBSD не поддерживают, хотя они экспортируют интерфейс, используемый Linux и Solaris для их поддержки. В таких системах этот интерфейс создает рекомендательные блокировки. Поддержка обязательных блокировок не распространяется на NFS.
{{cite web}}
: CS1 maint: unfit URL (link)