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

ЖАНРЫ

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

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

Шрифт:

6. Продолжите предыдущий пример, используя неблокируемую версию loopmain.с для создания программы loopnonenonb (используя файл locknone.c). Включите обязательную блокировку для файла seqno. Запустите один экземпляр этой программы и один экземпляр программы loopfcntlnonb из предыдущего примера одновременно. Что произойдет?

7. Создайте программу loopfcntl и запустите ее 10 раз в фоновом режиме из сценария интерпретатора команд. Каждому из 10 экземпляров следует указать аргумент 10000. Измерьте скорость работы сценария при использовании обязательной и рекомендательной блокировок. Как влияет обязательная блокировка на производительность?

8. Почему

мы вызывали fork в листингах 9.6 и 9.7 для порождения процессов, вместо того чтобы воспользоваться pthread_create для создания потоков?

9. В листинге 9.9 мы вызываем ftruncate для установки размера файла в 0 байт. Почему бы нам просто не указать флаг O_TRUNC при открытии файла?

10. Какой из констант — SEEK_SET, SEEK_CUR или SEEK_END — следует пользоваться при указании блокируемого диапазона при написании многопоточного приложения и почему? 

ГЛАВА 10

Семафоры Posix

10.1.Введение

Семафор представляет собой простейшее средство синхронизации процессов и потоков. Мы рассматриваем три типа семафоров:

■ именованные семафоры Posix, идентифицируемые именами, соответствующими стандарту Posix для IPC (см. раздел 2.2);

■ размещаемые в разделяемой памяти семафоры Posix;

■ семафоры System V (глава 11), обслуживаемые ядром.

Все три типа семафоров могут использоваться для синхронизации как отдельных процессов, так и потоков одного процесса. Мы начнем с рассмотрения проблем синхронизации между разными процессами с помощью бинарного семафора, то есть такого, который может принимать только значения 0 и 1. Пример подобной схемы приведен на рис. 10.1.

Рис. 10.1. Два процесса взаимодействуют с помощью бинарного семафора

На этом рисунке изображен бинарный семафор, хранящийся в ядре (семафор System V).

Семафоры Posix не обязательно должны обрабатываться ядром. Их особенностью является наличие имен, которые могут соответствовать именам реальных файлов в файловой системе. На рис. 10.2 изображена схема, лучше иллюстрирующая предмет обсуждения данной главы — именованный семафор Posix.

Рис. 10.2. Два процесса, использующие бинарный именованный семафор Posix

ПРИМЕЧАНИЕ

В отношении рис. 10.2 необходимо сделать одно уточнение: хотя именованные семафоры Posix обладают именами в файловой системе, они не обязательно должны храниться в файлах. Во встроенной системе реального времени значение семафора, скорее всего, будет размещаться в ядре, а имя файла будет использоваться исключительно для идентификации семафора. При реализации с помощью отображения файлов в память (пример такой реализации приведен в разделе 10.15) значение семафора будет действительно храниться в файле, который будет отображаться в адресное пространство всех процессов, использующих семафор. 

На рис. 10.1 и 10.2 мы указали три операции, которые могут быть применены к семафорам:

1. Создание семафора. При этом вызвавший процесс должен указать начальное значение (часто 1, но может быть и 0).

2. Ожидание изменения значения семафора (wait).

При этом производится проверка его значения и процесс блокируется, если значение оказывается меньшим либо равным 0, а при превышении 0 значение уменьшается на 1. Это может быть записано на псевдокоде как

while (semaphore_value <= 0); /* wait: т.е. поток или процесс блокируется */

semaphore_value--; /* семафор разрешает выполнение операций */

Основным требованием является атомарность выполнения операций проверки значения в цикле while и последующего уменьшения значения семафора (то есть как одной операции) по отношению к другим потокам (это одна из причин, по которой семафоры System V были реализованы в середине 80-х как часть ядра. Поскольку операции с ними выполнялись с помощью системных вызовов, легко было гарантировать их атомарность по отношению к другим процессам).

У этой операции есть несколько общеупотребительных имен. Изначально она называлась Р, от голландского proben (проверка, попытка), — это название было введено Эдсгером Дейкстрой. Используются также и термины down (поскольку значение семафора уменьшается) и lock, но мы будем следовать стандарту Posix и говорить об ожидании (wait). 

3. Установка значения семафора (post). Значение семафора увеличивается одной командой, которая может быть записана на псевдокоде как

semaphore_value++;

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

Для этой операции также имеется несколько общеупотребительных терминов. Изначально она называлась V, от голландского verhogen (увеличивать). Называют ее up (значение семафора увеличивается), unlock и signal. Мы, следуя стандарту Posix, называем эту операцию post.

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

Обратите внимание, что приведенный псевдокод не ограничен в применении только бинарными семафорами. Код работает с семафором, инициализируемым любым неотрицательным значением. Такие семафоры называют также семафорами-счетчиками. Обычно они инициализируются некоторым значением N, которое указывает количество доступных ресурсов (например, буферов). В этой главе есть примеры использования как бинарных семафоров, так и семафоров-счетчиков.

ПРИМЕЧАНИЕ

Мы часто проводим различие между бинарными и многозначными семафорами, но делаем это исключительно в образовательных целях. В системной реализации семафоров никакой разницы нет.

Бинарный семафор может использоваться в качестве средства исключения (подобно взаимному исключению). В листинге 10.1 приведен пример для сравнения этих средств.

Листинг 10.1. Сравнение бинарных семафоров и взаимных исключений

инициализация взаимного исключения; инициализация семафора единицей;

Поделиться с друзьями: