Читаем 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 / Словари и Энциклопедии
C# 4.0: полное руководство
C# 4.0: полное руководство

В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки. Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию

Герберт Шилдт

Программирование, программы, базы данных
C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

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