Чтение онлайн

на главную - закладки

Жанры

UNIX: взаимодействие процессов

Стивенс Уильям Ричард

Шрифт:

Установим значение последовательного номера в файле обратно в единицу и запустим программу в двух экземплярах в фоновом режиме. Результат будет такой:

solaris % locknone & locknone&

solaris % locknone: pid = 15498, seq# = 1

locknone: pid = 15498, seq# = 2

locknone: pid = 15498, seq# = 3

locknone: pid = 15498, seq# = 4

locknone: pid = 15498, seq# = 5

locknone: pid = 15498, seq# = 6

locknone: pid = 15498, seq# = 7

locknone: pid = 15498, seq# = 8

locknone: pid = 15498, seq# = 9

locknone: pid = 15498, seq# = 10

locknone: pid = 15498, seq# = 11

locknone: pid = 15498, seq# = 12

locknone: pid = 15498, seq# = 13

locknone: pid = 15498, seq# = 14

locknone: pid = 15498, seq# = 15

locknone: pid = 15498, seq# = 16

locknone: pid = 15498, seq# = 17

locknone: pid = 15498, seq# = 18

locknone: pid = 15498, seq# = 19

locknone: pid = 15498, seq# = 20

locknone: pid = 15499, seq# = 1

locknone: pid = 15499, seq# = 2

locknone: pid = 15499, seq# = 3

locknone: pid = 15499, seq# = 4

locknone: pid = 15499, seq# = 5

locknone: pid = 15499, seq# = 6

locknone: pid = 15499, seq# = 7

locknone: pid = 15499, seq# = 8

locknone: pid = 15499, seq# = 9

locknone: pid – 15499, seq# = 10

locknone: pid = 15499, seq# = 11

locknone: pid = 15499, seq# – 12

locknone: pid = 15499, seq# = 13

locknone: pid = 15499, seq# = 14

locknone: pid = 15499, seq# = 15

locknone: pid = 15499, seq# = 16

locknone: pid = 15499, seq# = 17

locknone: pid = 15499, seq# = 18

locknone: pid = 15499, seq# = 19

locknone: pid = 15499, seq# = 20

Первое, на что мы обращаем внимание, — подсказка интерпретатора, появившаяся до начала текста, выводимого программой. Это нормально и всегда имеет место при запуске программ в фоновом режиме.

Первые двадцать строк вывода не содержат ошибок. Они были сформированы первым экземпляром программы (с идентификатором 15 498). Проблема возникает в первой строке, выведенной вторым экземпляром (идентификатор 15499): он напечатал порядковый номер 1. Получилось это, скорее всего, так: второй процесс был запущен ядром, считал из файла порядковый номер (1), а затем управление было передано первому процессу, который работал до завершения. Затем второй процесс снова получил управление и продолжил выполняться с тем значением порядкового номера, которое было им уже считано (1). Это не то, что нам нужно. Каждый процесс считывает значение, увеличивает его и записывает обратно 20 раз (на экран выведено ровно 40 строк), поэтому конечное значение номера должно быть 40.

Нам нужно каким-то образом предотвратить изменение файла с порядковым номером на протяжении выполнения трех действий одним из процессов. Эти действия должны выполняться как атомарная операция по отношению к другим процессам. Код между вызовами my_lock и my_unlock представляет собой критическую область (глава 7).

При запуске двух экземпляров программы в фоновом режиме результат на самом деле непредсказуем. Нет никакой гарантии, что при каждом запуске мы будем получать один и тот же результат. Это нормально, если три действия будут выполняться как одна атомарная операция; в этом случае конечное значение порядкового номера все равно будет 40. Однако при неатомарном выполнении конечное значение часто будет отличным от 40, и это нас не устраивает. Например, нам безразлично, будет ли порядковый номер увеличен от 1 до 20 первым процессом и от 21 до 40 вторым или же процессы будут по очереди увеличивать его значение на единицу. Неопределенность не делает результат неправильным, а вот атомарность выполнения операций — делает. Однако неопределенность выполнения усложняет отладку программ.

9.2. Блокирование записей и файлов

Ядро Unix никак не интерпретирует содержимое файла, оставляя всю обработку записей приложениям, работающим с этим файлом. Тем не менее для описания предоставляемых возможностей используется термин «блокировка записей». В действительности приложение указывает диапазон байтов файла для блокирования или разблокирования. Сколько логических записей помещается в этот диапазон — значения не имеет.

Стандарт Posix определяет один специальный диапазон с началом в 0 (начало файла) и длиной 0 байт, который устанавливает блокировку для всего файла целиком. Мы будем говорить о блокировке записей, подразумевая блокировку файла как частный случай.

Термин «степень детализации» (granularity) используется для описания минимального размера блокируемого объекта. Для стандарта Posix эта величина составляет 1 байт. Обычно степень детализации связана с максимальным количеством одновременных обращений к файлу. Пусть, например, с некоторым файлом одновременно работают пять процессов, из которых три считывают данные из файла и два записывают в него. Предположим также, что каждый процесс работает со своим набором записей и каждый запрос требует примерно одинакового времени для обработки (1 секунда). Если блокировка осуществляется на уровне файла (самый низкий уровень детализации), три считывающих процесса смогут работать со своими записями одновременно, а двум записывающим придется ждать окончания их работы. Затем запись будет произведена сначала одним из оставшихся процессов, а потом другим. Полное затраченное время будет порядка 3 секунд (это, разумеется, очень грубая оценка). Если же уровень детализации соответствует размеру записи (наилучший уровень детализации), все пять процессов смогут работать одновременно, поскольку они обрабатывают разные записи. При этом на выполнение будет затрачена только одна секунда.

ПРИМЕЧАНИЕ

Потомки BSD поддерживают лишь блокировку файла целиком с помощью функции flock. Возможность заблокировать диапазон байтов не предусматривается. 

История

За долгие годы было разработано множество методов блокировки файлов и записей. Древние программы вроде UUCP и демонов печати играли на реализации файловой системы (три из них описаны в разделе 9.8). Они работали достаточно медленно и не подходили для баз данных, которые стали появляться в начале 80-х.

Первый раз возможность блокировать файлы и записи появилась в Version 7, куда она была добавлена Джоном Бассом John Bass) в 1980 году в виде нового системного вызова locking. Это блокирование было обязательным (mandatory locking); его унаследовали многие версии System III и Xenix. (Разница между обязательным и рекомендательным блокированием и между блокированием записей и файлов описана далее в этой главе.)

Версия 4.2BSD предоставила возможность блокирования файлов (а не записей) функцией flock в 1983. В 1984 году стандарт /usr/group (один из предшественников Х/Open) определил функцию lockf, которая осуществляла только исключающую блокировку (на запись), но не совместную.

Поделиться:
Популярные книги

Я до сих пор царь. Книга XXXII

Дрейк Сириус
32. Дорогой барон!
Фантастика:
юмористическое фэнтези
аниме
попаданцы
5.00
рейтинг книги
Я до сих пор царь. Книга XXXII

Путь Шедара

Кораблев Родион
4. Другая сторона
Фантастика:
боевая фантастика
6.83
рейтинг книги
Путь Шедара

Отморозок 3

Поповский Андрей Владимирович
3. Отморозок
Фантастика:
попаданцы
5.00
рейтинг книги
Отморозок 3

Тринадцатый VI

NikL
6. Видящий смерть
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Тринадцатый VI

Матабар V

Клеванский Кирилл Сергеевич
5. Матабар
Фантастика:
фэнтези
5.00
рейтинг книги
Матабар V

Дважды одаренный. Том VI

Тарс Элиан
6. Дважды одаренный
Фантастика:
аниме
альтернативная история
фэнтези
фантастика: прочее
5.00
рейтинг книги
Дважды одаренный. Том VI

Идеальный мир для Лекаря 23

Сапфир Олег
23. Лекарь
Фантастика:
юмористическое фэнтези
аниме
фэнтези
5.00
рейтинг книги
Идеальный мир для Лекаря 23

Кодекс Охотника. Книга XIX

Винокуров Юрий
19. Кодекс Охотника
Фантастика:
фэнтези
5.00
рейтинг книги
Кодекс Охотника. Книга XIX

Старый, но крепкий 3

Крынов Макс
3. Культивация без насилия
Фантастика:
рпг
уся
фэнтези
5.00
рейтинг книги
Старый, но крепкий 3

Эмиссар

Листратов Валерий
8. Ушедший Род
Фантастика:
боевая фантастика
аниме
попаданцы
7.50
рейтинг книги
Эмиссар

Сочинения

Гюго Виктор
Проза:
классическая проза
5.00
рейтинг книги
Сочинения

Истребители. Трилогия

Поселягин Владимир Геннадьевич
Фантастика:
альтернативная история
7.30
рейтинг книги
Истребители. Трилогия

Искатель 1

Шиленко Сергей
1. Валинор
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Искатель 1

Дочь моего друга

Тоцка Тала
2. Айдаровы
Любовные романы:
современные любовные романы
эро литература
5.00
рейтинг книги
Дочь моего друга