Читаем Linux API. Исчерпывающее руководство полностью

Допустим, для файла включена строгая блокировка. Что произойдет, если системный вызов, который передает данные (то есть выполняет операции вроде read() или write()), сталкивается с конфликтующей блокировкой (то есть пытается записать или прочитать данные с участка, заблокированного для чтения или записи)? Ответ зависит от того, в каком режиме был открыт файл — блокирующем или неблокирующем. В первом случае системный вызов блокируется, а во втором — немедленно завершается ошибкой EAGAIN. По похожему принципу работают вызовы truncate() и ftruncate(), когда пытаются добавить или удалить данные с участка, покрытого блокировкой (для чтения или записи), принадлежащей другому процессу.

При открытии файла в блокирующем режиме (то есть если в вызове open() не был указан флаг O_NONBLOCK) системные вызовы для ввода/вывода могут привести к взаимной блокировке. Взгляните на пример, представленный на рис. 51.7: два процесса, открывшие один и тот же файл в блокирующем режиме, получают блокировки для записи на разные участки этого файла и затем каждый из них пытается выполнить запись на участок, заблокированный другим процессом. Ядро выходит из данной ситуации так же, как в случае с двумя вызовами fcntl(), блокирующими друг друга (см. подраздел 51.3.1): выбирает один заблокированный процесс и делает так, чтобы его операция write() завершилась ошибкой EDEADLK.

Любая попытка открыть файл с флагом O_TRUNC сразу же завершается неудачей (ошибкой EAGAIN), если в любой части того же файла другой процесс удерживает блокировку для чтения или записи.

Если к любой части файла применяется строгая блокировка для чтения или записи, то для него невозможно создать разделяемое отображение в память (то есть выполнить mmap() с флагом MAP_SHARED). И наоборот: если файл каким-либо образом используется в разделяемом отображении, то строгую блокировку невозможно применить ни к одной его части. В обоих случаях соответствующий системный вызов немедленно завершается ошибкой EAGAIN. Причина этого ограничения становится понятной, если проанализировать то, как реализованы отображения в память. В подразделе 45.4.2 мы увидели, что разделяемые файловые отображения применяют файл как для чтения, так и для записи (в частности, запись конфликтует с любым видом блокировки для того же файла). Кроме того, данный ввод/вывод выполняется подсистемой управления памятью, не имеющей ни малейшего представления о местоположении каких-либо файловых блокировок. Следовательно, чтобы не дать отображению обновить файл, для которого установлена строгая блокировка, ядро производит простую проверку: в момент вызова mmap() оно ищет любые блокировки в файле, подлежащем отображению (обратная процедура выполняется для вызова fcntl()).

Рис. 51.7. Взаимная блокировка в случае поддержки строгих блокировок

Неочевидные аспекты строгой блокировки

Строгая блокировка не настолько удобна, как можно было бы ожидать. К тому же она имеет ряд недостатков.

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

• Прежде чем применять строгую блокировку к публично доступному файлу, стоит тщательно все обдумать, так как ее нельзя переопределить даже привилегированным процессом. Злоумышленник может совершить DoS-атаку, постоянно удерживая блокировку (в большинстве случаев файл можно снова сделать доступным, отключив бит установки группового идентификатора, но иногда это не представляется возможным — например, если строгая блокировка привела к зависанию системы).

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

• Строгая блокировка также влияет на архитектуру приложения. Следует учитывать, что любая операция ввода/вывода может вернуть ошибку EAGAIN (для неблокирующего ввода/вывода) или EDEADLK (для блокирующего ввода/вывода).

• Ряд случаев состояния гонки в текущей реализации ядра Linux приводит к тому, что системные вызовы, выполняющие ввод/вывод, в отдельных ситуациях могут завершиться успешно даже при наличии строгих блокировок, которые должны были бы их отклонить.

В целом применения строгих блокировок лучше избегать.

51.5. Файл /proc/locks

Список блокировок, удерживаемых в системе, можно просмотреть в файле /proc/locks (доступном только в Linux). Ниже показан пример его содержимого (в данном случае в нем находятся сведения о четырех блокировках):

$ cat /proc/locks

1: POSIX ADVISORY WRITE 458 03:07:133880 0 EOF

2: FLOCK ADVISORY WRITE 404 03:07:133875 0 EOF

3: POSIX ADVISORY WRITE 312 03:07:133853 0 EOF

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных