Харт Джонсон М.
Шрифт:
dwReserved — значение этого параметра должно устанавливаться равным 0. Следующие два параметра определяют соответственно младшие и старшие 32-битовые значения размера блокируемого участка файла (в байтах).
lpOverlapped — указатель на структуру данных OVERLAPPED, содержащую информацию о начале блокируемого участка. В этой структуре необходимо устанавливать значения трех элементов (остальные элементы игнорируются), первые два из которых определяют смещение начала блокируемого участка от начала файла.
• DWORD Offset (используется именно такое имя параметра, а не OffsetLow).
• DWORD OffsetHigh.
• HANDLE hEvent должен задаваться равным 0.
Чтобы разблокировать файл, следует вызвать функцию UnlockFileEx, все параметры которой, за исключением dwFlags, совпадают с параметрами предыдущей функции:
Используя блокирование файлов, вы должны принимать во внимание следующие обстоятельства:
• Границы области разблокирования должны в точности совпадать с границами ранее заблокированной области. Не допускается, например, объединение двух ранее заблокированных областей или разблокирование части заблокированной области. Любая попытка разблокирования области, не совпадающей в точности с одной из существующих заблокированных областей, будет неудачной. В этом случае функция вернет значение FALSE, а в выведенном системой сообщении об ошибке будет указано, что данная область блокирования не существует.
• Вновь создаваемая и существующие области блокирования в файле не могут перекрываться, если это приводит к возникновению конфликтной ситуации.
• Возможно блокирование участка, границы которого выходят за пределы файла. Такая операция может оказаться полезной в случае расширения файла процессом или потоком.
• Блокировки не наследуются вновь создаваемыми процессами.
Логику процедуры блокирования, когда вся область или только некоторая ее часть уже содержат заблокированные участки, иллюстрирует табл. 3.1.
Таблица 3.1. Логика предоставления блокировки
| Тип запрашиваемой блокировки | ||
|---|---|---|
| Существующая блокировка | Разделяемая блокировка | Монопольная блокировка |
| Отсутствует | Предоставляется | Предоставляется |
| Разделяемая блокировка (одна или несколько) | Предоставляется | Отказ |
| Монопольная блокировка | Отказ | Отказ |
Логику предоставления возможности выполнения операций чтения/записи во всей или части области файла, содержащей участки с одной или несколькими блокировками, владельцами которых являются другие процессы, иллюстрирует табл. 3.2.
Таблица 3.2. Блокировки и выполнение операций ввода/вывода
| Операция ввода/вывода | ||
|---|---|---|
| Существующая блокировка | Чтение | Запись |
| Отсутствует | Успешно выполняется | Успешно выполняется |
| Разделяемая блокировка (одна или несколько) | Выполняется. Вызывающий процесс не обязан быть владельцем блокировки данной области файла. | Не выполняется |
| Монопольная блокировка | Выполняется, если вызывающий процесс является владельцем блокировки, в противном случае — неудачное завершение. | Выполняется, если вызывающий процесс является владельцем блокировки, в противном случае — неудачное завершение. |
Обычно операции чтения и записи выполняются путем вызова функций Read-File и WriteFile или их расширенных версий ReadFileEx и WriteFileEx. Для диагностики ошибок, возникающих в процессе выполнения операций ввода/вывода, следует вызывать функцию GetLastError.
Одна из разновидностей операций ввода/вывода с участием файлов предполагает использование отображения файлов, которое обсуждается в главе 5. Обнаружение конфликтов блокировки на этапе обращения к памяти не производится; такая проверка осуществляется во время вызова функции MapViewOfFile. Указанная функция делает часть файла доступной для процесса, вследствие чего проверка наличия блокировок на этом этапе является необходимой.
Разновидностью функции LockFileEx с ограниченной сферой применимости является функция LockFile, вызов которой, скорее, лишь уведомляет о намерении осуществить блокировку. Эту функцию можно использовать в системах Windows 9x, которые не поддерживают функцию LockFileEx. Функция LockFile предоставляет блокирующему процессу только монопольный доступ, а возврат из функции происходит сразу же. Таким образом, функция LockFile не блокируется. Проверить, предоставлена блокировка или нет, можно путем тестирования возвращаемого функцией значения.