Подтвердить что ты не робот

Fcntl, lockf, который лучше использовать для блокировки файлов?

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

4b9b3361

Ответ 1

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

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

Источник

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

Источник

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

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


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

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

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

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

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


Как принудительные блокировки работают в Linux:

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


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

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

Ответ 2

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

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

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

Ответ 3

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

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

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

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

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

Ответ 4

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

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

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

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

fseek (fileHandle, 0, SEEK_SET);//перейдите в начало

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

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

Ответ 5

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

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

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