В каком порядке система POSIX снимает блокировки файлов, которые не были полностью разблокированы?

В спецификации POSIX для fcntl() указано:

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

Является ли эта операция разблокировки блокировок файловых сегментов, удерживаемых завершившимся процессом, атомарной для каждого файла? Другими словами, если процесс заблокировал сегменты байтов B1..B2 и B3..B4 файла, но не разблокировал сегменты до завершения, когда система сможет разблокировать их, это будут сегменты B1..B2 и B3. .B4 оба разблокированы до того, как другая fcntl() операция по блокировке сегмента файла может быть успешной? Если не атомарный для каждого файла, зависит ли порядок, в котором эти сегменты файлов разблокируются системой, от порядка, в котором сегменты файлов были первоначально получены?

Спецификация для fcntl() ничего не говорит, но, возможно, в спецификации POSIX есть общее положение, которое предписывает детерминированный порядок операций для очистки после нечистоплотного завершения процесса или сбоя.


person Daniel Trebbien    schedule 01.10.2011    source источник
comment
Просто из любопытства, зачем тебе это? (Создание ситуации, которая зависит от порядка снятия блокировки, требует некоторых усилий... По крайней мере, я так думал.)   -  person Nemo    schedule 01.10.2011
comment
@Nemo: я извлек — по крайней мере, я так думаю — алгоритмы блокировки файлов SQLite, чтобы я мог реализовать транзакции на основе блокировки файлов для произвольного содержимого файлов. Алгоритмы реализуются с блокировкой трех сегментов, а иногда и двух из них блокируются одновременно. Одно различие между моей версией и версией SQLite заключается в том, что я жду блокировки файлов, тогда как они выбирают повторную попытку определенное количество раз, засыпая между попытками. Мне кажется, что они не блокируют на блокировки, потому что хотят совместимости с Win98, но я пытаюсь определить, есть ли другая причина.   -  person Daniel Trebbien    schedule 01.10.2011


Ответы (2)


Частичный ответ содержится в разделе 2.9.7, Взаимодействие потоков с обычными файловыми операциями спецификации POSIX:

Все функции chmod() , close(), fchmod(), fcntl(), fstat(), ftruncate(), lseek(), open(), read(), readlink(), stat< /em>(), символическая ссылка () и написать() должны быть атомарными по отношению друг к другу в эффектах, указанных в IEEE Std 1003.1-2001, когда они работают с обычными файлами. Если каждый из двух потоков вызывает одну из этих функций, каждый вызов должен либо видеть все указанные эффекты другого вызова, либо ни один из них.

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

В спецификации для exit() указано:

Эти функции должны завершать вызывающий процесс со следующими последствиями:

  • Все дескрипторы файлов, потоки каталогов [, дескрипторы преобразования и дескрипторы каталога сообщений], открытые в вызывающем процессе, должны быть закрыты.

  • ...

Предположительно, дескрипторы открытых файлов закрываются как будто соответствующими вызовами close(), но, к сожалению, в спецификации не сказано, как закрываются дескрипторы открытых файлов.

Спецификация 2004 года кажется еще более расплывчатой, когда речь заходит об этапах аномального завершения процесса. Единственное, что мне удалось найти, это документацию для abort(). По крайней мере, в спецификации 2008 года есть раздел под названием Последствия завершения процесса. на странице для _Exit(). Однако формулировка остается прежней:

  • Все дескрипторы файлов, потоки каталогов, дескрипторы преобразования и дескрипторы каталога сообщений, открытые в вызывающем процессе, должны быть закрыты.

ОБНОВЛЕНИЕ: я только что открыл проблему 0000498 в средстве отслеживания дефектов группы Austin. а>.

person Daniel Trebbien    schedule 01.10.2011

Я не думаю, что спецификация POSIX оговаривает, является ли снятие блокировок атомарным или нет, поэтому вы должны исходить из того, что это ведет себя максимально неудобно для вас. Если вам нужно, чтобы они были атомарными, это не так; если вам нужно, чтобы они обрабатывались отдельно, они атомарны; если вам все равно, некоторые машины будут делать это одним способом, а другие – другим. Итак, напишите свой код так, чтобы это не имело значения.

Я не уверен, как бы вы написали код для обнаружения проблемы.

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

person Jonathan Leffler    schedule 01.10.2011
comment
Привет Джонатан. Спасибо за Ваш ответ. В итоге я прочитал раздел 2.9.7, который отвечает на вопрос для обычных файлов и когда процесс нечисто закрывает файловый дескриптор, связанный с файлом. Однако, похоже, проблемы с формулировкой последствий завершения процесса. - person Daniel Trebbien; 02.10.2011
comment
Несмотря на то, что спецификация требует определенного поведения, я думаю, что последую вашему совету и предположу иначе, потому что могут быть проблемы с системой POSIX, которые делают ее несовместимой. - person Daniel Trebbien; 02.10.2011