fcntl, lockf, что лучше использовать для блокировки файлов? - PullRequest
45 голосов
/ 22 февраля 2009

Требуется информация о преимуществах и недостатках обоих fcntl и lockf для блокировки файлов. Например, что лучше использовать для мобильности? В настоящее время я пишу код демона linux и задаюсь вопросом, что лучше использовать для принудительного взаимного исключения.

Ответы [ 5 ]

61 голосов
/ 22 февраля 2009

В чем разница между lockf и fcntl:

Во многих системах библиотечная подпрограмма lockf() является просто оболочкой для fcntl(). То есть lockf предлагает подмножество функций, которые fcntl делает.

Источник

Но в некоторых системах блокировки fcntl и lockf полностью независимы.

Источник

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

Какой из них вы выбрали, не имеет значения.


Некоторые примечания об обязательных и консультативных блокировках:

Блокировка в unix / linux по умолчанию рекомендация , что означает, что другие процессы не должны следовать установленным правилам блокировки. Поэтому не имеет значения, каким образом вы блокируете, если ваши взаимодействующие процессы также используют то же соглашение.

Linux поддерживает обязательную блокировку, но только если ваша файловая система смонтирована с включенным параметром и специальными атрибутами файла. Вы можете использовать mount -o mand для монтирования файловой системы и установить атрибуты файла g-x,g+s для включения обязательных блокировок, затем используйте fcntl или lockf. Для получения дополнительной информации о том, как работают обязательные блокировки, см. здесь .

Обратите внимание, что блокировки применяются не к отдельному файлу, а к индексу. Это означает, что 2 имени файла, которые указывают на одни и те же данные файла, будут иметь одинаковый статус блокировки.

В Windows, с другой стороны, вы можете активно открывать файл исключительно, и это не позволит другим процессам полностью его открыть. Даже если они хотят. Т.е. замки обязательны. То же самое касается Windows и блокировки файлов. Любой процесс с дескриптором открытого файла с соответствующим доступом может заблокировать часть файла, и никакой другой процесс не сможет получить доступ к этой части.


Как работают обязательные блокировки в Linux:

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


Предупреждение NFS:

Будьте осторожны, если вы используете команды блокировки при монтировании NFS. Поведение не определено, и реализация широко варьируется, использовать ли только локальную блокировку или поддерживать удаленную блокировку.

10 голосов
/ 22 февраля 2009

Оба интерфейса являются частью стандарта POSIX, и в настоящее время оба интерфейса доступны в большинстве систем (я только что проверил Linux, FreeBSD, Mac OS X и Solaris). Поэтому выберите тот, который лучше соответствует вашим требованиям, и используйте его.

Одно слово предостережения: неизвестно, что происходит, когда один процесс блокирует файл с помощью fcntl, а другой - с помощью lockf. В большинстве систем это эквивалентные операции (фактически в Linux блокировка f реализована поверх fcntl), но POSIX говорит, что их взаимодействие не определено. Поэтому, если вы взаимодействуете с другим процессом, который использует один из двух интерфейсов, выберите тот же.

Другие писали, что блокировки носят исключительно рекомендательный характер: вы несете ответственность за проверку того, заблокирован ли регион. Кроме того, не используйте функции stdio, если вы хотите использовать функцию блокировки.

9 голосов
/ 22 февраля 2009

Ваши основные проблемы в этом случае (т. Е. Когда " кодирует демон Linux и задается вопросом, что лучше использовать для для принудительного взаимного исключения "), должно быть:

  1. будет ли заблокированный файл локальным или может быть в NFS?
    • например. может ли пользователь заставить вас создать и заблокировать pid-файл вашего демона в NFS?
  2. как будет вести себя блокировка при fork ing или когда процесс демона завершается с предубеждением, например, kill -9

Команды flock и fcntl ведут себя по-разному в обоих случаях.

Я рекомендую использовать fcntl. Вы можете обратиться к статье о блокировке файлов в Википедии для подробного обсуждения проблем, связанных с обоими решениями:

У flock и fcntl есть причуды, которые иногда программисты головоломки из другие операционные системы. Будь стая блокирует работу на сетевых файловых системах, такой как NFS, это реализация зависимый. На системах BSD стекаются звонки успешные ноуты На Linux предшествующий 2.6.12 вызовы стекаются по файлам NFS будет действовать только локально. Ядро 2.6.12 и выше реализовать стая вызовов на NFS файлы, использующие блокировки диапазона байтов POSIX. Эти замки будут видны другим Клиенты NFS, которые реализуют fcntl () / POSIX блокирует. 1 Блокирует обновления и понижения освобождают старый замок перед применением нового замка. Если приложение понижает эксклюзивный заблокировать общий замок, в то время как другой приложение заблокировано в ожидании эксклюзивный замок, последнее приложение получит эксклюзивный замок и Первое приложение будет заблокировано. Все блокировки fcntl, связанные с файлом для данного процесса удаляются, когда любой дескриптор файла для этого файла закрыт этим процессом, даже если блокировка никогда не запрашивался для этого файла дескриптор. Кроме того, fcntl блокировки не наследуется дочерним процессом. fcntl близкая семантика особенно хлопотно для приложений, которые вызывать подпрограммы библиотеки, которые могут доступ к файлам.

7 голосов
/ 17 сентября 2014

Я недавно столкнулся с проблемой при использовании fcntl и flock, и мне показалось, что я должен сообщить здесь, так как поиск любого термина показывает, что эта страница находится в верхней части обоих.

Имейте в виду, что замки BSD, как упомянуто выше, рекомендуют . Для тех, кто не знает, OSX (дарвин) - это BSD. Это необходимо запомнить при открытии файла для записи.

Чтобы использовать fcntl / flock, вы должны сначала открыть файл и получить его идентификатор. Однако, если вы открыли файл с «w», файл мгновенно обнулится . Если ваш процесс не сможет получить блокировку, поскольку файл используется в другом месте, он, скорее всего, вернется, оставив файл как 0 КБ. Процесс, который имел блокировку, теперь обнаружит, что файл исчез из-под него, обычно следуют катастрофические результаты.

Чтобы исправить эту ситуацию, при использовании блокировки файлов, никогда никогда не открывать файл "w", а вместо этого открывать его "a", чтобы добавить. Затем, если блокировка успешно получена, вы можете безопасно очистить файл так, как если бы он был «w», т.е. :

fseek (fileHandle, 0, SEEK_SET); // перейти к началу

ftruncate (fileno ((FILE *) fileHandle), 0); // очистить его

Это был неприятный урок для меня.

1 голос
/ 22 февраля 2009

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

Уловка с механизмами блокировки файлов должна быть последовательной - используйте один и придерживайтесь его. Изменение их - плохая идея.

Я предполагаю, что файловая система будет локальной - если это не так, то все ставки выключены, NFS / другие сетевые файловые системы обрабатывают блокировку с различной степенью эффективности (в некоторых случаях - нет)

...