9.8. Блокирование файлов
9.8. Блокирование файлов
Стандарт Posix.1 гарантирует, что если функция open вызывается с флагами O_CREAT (создать файл, если он еще не существует) и O_EXCL (исключающее открытие), функция возвращает ошибку, если файл уже существует. Более того, проверка существования файла и его создание (если он еще не существует) должны представлять собой атомарную по отношению к другим процессам операцию. Следовательно, мы можем использовать создаваемый таким методом файл как блокировку. Можно быть уверенным, что только один процесс сможет создать файл (то есть получить блокировку), а для снятия этой блокировки файл можно удалить командой unlink.
В листинге 9.9 приведен текст наших функций установки и снятия блокировки, использующих этот метод. При успешном выполнении функции open мы считаем, что блокировка установлена, и успешно возвращаемся из функции my_lock. Файл мы закрываем, потому что его дескриптор нам не нужен. О наличии блокировки свидетельствует само существование файла вне зависимости от того, открыт он или нет. Если функция open возвращает ошибку EEXIST, значит, файл существует и мы должны еще раз попытаться открыть его.
У этого метода есть три недостатка.
1. Если процесс, установивший блокировку, завершится досрочно, не сняв ее, файл не будет удален. Существуют способы борьбы с этой проблемой, например проверка времени доступа к файлу и удаление его спустя некоторый определенный промежуток времени, — но все они несовершенны. Другое решение заключается в записи в файл идентификатора процесса, чтобы другие процессы могли считать его и проверить, существует ли еще такой процесс. Этот метод также несовершенен, поскольку идентификатор может быть использован повторно.
В такой ситуации лучше пользоваться блокировкой fcntl, которая автоматически снимается по завершении процесса.
2. Если файл открыт каким-либо другим процессом, мы должны еще раз вызвать open, повторяя эти вызовы в бесконечном цикле. Это называется опросом и является напрасной тратой времени процессора. Альтернативным методом является вызов sleep на 1 секунду, а затем повторный вызов open (этапроблема обсуждалась в связи с листингом 7.4).
Эта проблема также исчезает при использовании блокировки fcntl, если использовать команду F_SETLKW. Ядро автоматически приостанавливает выполнение процесса до тех пор, пока ресурс не станет доступен.
3. Создание и удаление файла вызовом open и unlink приводит к обращению к файловой системе, что обычно занимает существенно больше времени, чем вызов fcntl (обращение производится дважды: один раз для получения блокировки, а второй — для снятия). При использовании fcntl программа выполнила 10000 повторов цикла с увеличением порядкового номера в 75 раз быстрее, чем программа, вызывавшая open и unlink.
Листинг 9.9. Функции блокировки с использованием open с флагами O_CREAT и O_EXCL
//lock/lockopen.c
1 #include "unpipc.h"
2 #define LOCKFILE "/tmp/seqno.lock"
3 void
4 my_lock(int fd)
5 {
6 int tempfd;
7 while ((tempfd = open(LOCKFILE, O_RDWR|O_CREAT|O_EXCL, FILE_MODE)) < 0) {
8 if (errno != EEXIST)
9 err_sys("open error for lock file");
10 /* блокировка установлена кем-то другим, повторяем попытку */
11 }
12 Close(tempfd); /* открыли файл, блокировка установлена */
13 }
14 void
15 my_unlock(int fd)
16 {
17 Unlink(LOCKFILE); /* снимаем блокировку удалением файла */
18 }
Есть еще две особенности файловой системы Unix, которые использовались для реализации блокировок. Первая заключается в том, что функция link возвращает ошибку, если имя новой ссылки уже существует. Для получения блокировки создается уникальный временный файл, полное имя которого содержит в себе его идентификатор процесса (или комбинацию идентификаторов процесса и потока, если требуется осуществлять блокировку между отдельными потоками). Затем вызывается функция link для создания ссылки на этот файл с каким-либо определенным заранее именем. После успешного создания сам файл может быть удален вызовом unlink. После осуществления работы с блокировкой файл с известным именем удаляется командой unlink. Если link возвращает ошибку EEXIST, поток должен попытаться создать ссылку еще раз (аналогично листингу 9.9). Одно из требований к этому методу — необходимо, чтобы и временный файл, и ссылка находились в одной файловой системе, поскольку большинство версий Unix не допускают создания жестких ссылок (результат вызова link) в разных файловых системах.
Вторая особенность заключается в том, что функция open возвращает ошибку в случае существования файла, если указан флаг O_TRUNC и запрещен доступ на запись. Для получения блокировки мы вызываем open, указывая флаги O_CREAT | O_WRONLY | O_TRUNC и аргумент mode со значением 0 (то есть разрешения на доступ к файлу установлены в 0). Если вызов оказывается успешным, блокировка установлена и мы просто удаляем файл вызовом unlink после завершения работы. Если вызов open возвращает ошибку EACESS, поток должен сделать еще одну попытку (аналогично листингу 9.9). Этот трюк не срабатывает, если поток обладает правами привилегированного пользователя.
Урок, который можно извлечь из этих примеров, прост: нужно пользоваться блокировкой fcntl. Тем не менее вы можете столкнуться с программой, в которой используются старые методы блокировки, и особенно часто это будет встречаться в программах, написанных до широкого распространения реализации с блокировкой fcntl.
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКДанный текст является ознакомительным фрагментом.
Читайте также
14.2.3. Блокирование BSD: flock()
14.2.3. Блокирование BSD: flock() 4.2 BSD представило свой собственный механизм блокировки, flock()[155]. Функция объявлена следующим образом:#include <sys/file.h> /* Обычный */int flock(int fd, int operation);Дескриптор fd представляет открытый файл. Имеются следующие операции:LOCK_SH Создает совместную
Блокирование файлов
Блокирование файлов В системах, допускающих одновременное выполнение нескольких процессов, особую актуальность приобретает проблема координации и синхронизации доступа к разделяемым (совместно используемым) объектам, например файлам.В Windows имеется возможность
11. Блокирование Tor и как с ним бороться
11. Блокирование Tor и как с ним бороться Система Tor позволяет скрывать от провайдера конечные (целевые) адреса, тем самым прорывая возможную блокаду доступа к заблокированным им сетевым ресурсам. Также система Tor скрывает от целевых ресурсов адрес отправителя, тем самым
Блокирование доступа к файлу
Блокирование доступа к файлу Традиционно архитектура файловой подсистемы UNIX разрешает нескольким процессам одновременный доступ к файлу для чтения и записи. Хотя операции записи и чтения, осуществляемые с помощью системных вызовов read(2) или write(2), являются атомарными, в
9.2. Блокирование записей и файлов
9.2. Блокирование записей и файлов Ядро Unix никак не интерпретирует содержимое файла, оставляя всю обработку записей приложениям, работающим с этим файлом. Тем не менее для описания предоставляемых возможностей используется термин «блокировка записей». В
9.8. Блокирование файлов
9.8. Блокирование файлов Стандарт Posix.1 гарантирует, что если функция open вызывается с флагами O_CREAT (создать файл, если он еще не существует) и O_EXCL (исключающее открытие), функция возвращает ошибку, если файл уже существует. Более того, проверка существования файла и его
9.9. Блокирование в NFS
9.9. Блокирование в NFS Аббревиатура NFS расшифровывается как Network File System (сетевая файловая система); эта система подробно обсуждается в главе 29 [22]. Блокировка записей fcntl представляет собой расширение NFS, поддерживаемое большинством ее реализаций. Обслуживается эта
10.7. Блокирование файлов
10.7. Блокирование файлов Вернемся к задаче о порядковом номере из главы 9. Здесь мы напишем новые версии функций my_lock и my_unlосk, использующие именованные семафоры Posix. В листинге 10.10 приведен текст этих функций.Листинг 10.10. Блокирование файла с помощью именованных семафоров
11.6. Блокирование файлов
11.6. Блокирование файлов С помощью семафоров System V можно реализовать еще одну версию функций my_lock и my_unlock из листинга 10.10. Новый вариант приведен в листинге 11.6.Листинг 11.6. Блокировка файлов с помощью семафоров System V//lock/locksvsem.c1 #include "unpipc.h"2 #define LOCK_PATH "/tmp/svsemlock"3 #define MAX_TRIES
Блокирование объектов
Блокирование объектов В заключение главы, посвященной редактированию объектов, упомянем о механизме, позволяющем избежать случайного изменения объектов или их свойств. В ArchiCAD есть способ защитить необходимые объекты от редактирования. Для этого следует выделить их и
Блокирование объектов
Блокирование объектов В заключение главы, посвященной редактированию объектов, упомяну о механизме, позволяющем избежать случайного изменения объектов или их свойств. В ArchiCAD имеется способ заблокировать необходимые объекты от редактирования. Для этого следует
Цензура и блокирование интернета
Цензура и блокирование интернета http://habrahabr.ru/post/155295/Этапы введения цензуры в интернете 2007–201218 октября 2012 в 19:22.Копирайт: Dura Lex.Глядя на то, как в отдельных областях России блокируется youtube и ubuntu, я не мог не вспомнить, как Кристиан Энгстрём и Рик Фальквинге в брошюре,
17.4.7. Блокирование нежелательных корреспондентов
17.4.7. Блокирование нежелательных корреспондентов Если вам надоел какой-то корреспондент и вы больше не хотите получать от него письма, можете внести его в список блокируемых. Для этого щелкните на любом письме от этого корреспондента и выполните команду меню Сообщение,
Блокирование активного содержимого
Блокирование активного содержимого Веб-страницы могут содержать не только тексты и рисунки, но и специальные программные модули, расширяющие возможности веб-страниц и позволяющие сделать их интерактивными. Однако в то же время этими средствами могут воспользоваться