Unix - статьи

       

Блокировка областей файла


Блокировка областей файла позволяет нескольким программам совместно работать с содержимым одного и того же файла, не мешая друг другу, или, точнее, мешая друг другу испортить данные. Мы рассмотрим интерфейс блокировки областей, основанный на использовании функции fcntl(2). Функция fcntl() тоже представляет собой нечто вроде швейцарского армейского ножа. С помощью этой функции можно манипулировать дескрипторами файлов и устанавливать рекомендательные (advisory) блокировки. Рекомендательными эти блокировки называются потому, что следование им является для программ, работающих с файлом, делом доброй воли. Если программа сама не использует блокировок, блокировки, установленные другими программами, не будут иметь для нее никакого эффекта. Существует возможность придать рекомендательным блокировкам fcntl() обязательный характер, но для этого соответствующая файловая система должна быть смонтирована со специальным ключом. Для изучения работы блокировок напишем программу testlocks (файл testlocks.c). При работе с блокировками во втором параметре функции fcntl() передается одна из команд управления блокировками, третий же параметр должен содержать адрес структуры flock, в которую записывается информация о блокировке (см. таблицу 3).

Поле Значение

l_type Тип блокировки: записи – F_RDLCK, чтения – F_WRLCK, сброс – F_UNLCK.
l_whence Точка отсчета смещения
l_start Начальный байт области
l_len Длина области
l_pid Идентификатор процесса, установившего блокировку (для GETLCK)

Таблица 3.Описание полей структуры f_lock

Для установки блокировки мы заполняем поля структуры flock необходимыми значениями и вызываем fcntl() с командой F_SETLK (установить блокировку):

fi.l_type = F_WRLCK; fi.l_whence = SEEK_SET; fi.l_start = 0; fi.l_len = 64; off = 0; while (fcntl(fd, F_SETLK, &fi) == -1) { fcntl(fd, F_GETLK, & fi); ... printf("байты %i - %i заблокированы процессом %i\n", off, off+64, fi.l_pid); }

Если заданная область уже заблокирована, fcntl возвращает -1. С помощью команды F_GETLK можно узнать, идентификатор процесса, заблокировавшего данную область. Для того, чтобы снять блокировку, мы вызываем fctnl() с командой F_SETLK (странно, не правда ли?) и параметром l_type структуры flock, равным F_UNLCK: fi.l_type = F_UNLCK; if (fcntl(fd, F_SETLK, &fi) == -1) printf("Ошибка разблокирования\n");

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

Файлы Linux, – это не только удобные хранилища данных. С их помощью можно решать множество задач, начиная с управления устройствами и заканчивая разграничением доступа к ресурсам. Однако, работа с файлами – далеко не единственное, что может Linux.



Содержание раздела