26.6. Семафоры

26.6. Семафоры

Семафор — это объект IPC, управляющий доступом к общим ресурсам (устройствам). Семафоры не позволяют одному процессу захватить устройство до тех пор, пока с этим устройством работает другой процесс. Семафор может находиться в двух положениях: 0 (устройство занято) и 1 (устройство свободно).

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

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

Как и в случае с очередями сообщений, для семафоров в ядре Linux есть своя структура — semid_ds, которая описана в файле /usr/src/linux/include/linux/sem.h:

struct semid_ds {

 struct ipc_perm sem_perm; /* права доступа */

 time_t sem_otime; /* время последней операции */

 time_t sem_ctime; /* время последнего изменения */

 struct sem *sem_base; /* указатель на первый семафор */

 struct wait_queue *eventn; /* очереди ожидания */

 struct wait_queue *eventz;

 struct sem_undo *undo; /* запросы undo в этом массиве */

 ushort sem_nsems; /* номера семафоров в массиве */

};

Обратите внимание: в структуре есть указатель на первый семафор. Тип указателя — sem. Данный тип описывает семафор:

struct sem {

 short sempid; /* pid последней операции */

 ushort semval; /* текущее значение семафора */

 ushort semncnt; /* число процессов, ожидающих

                    освобожд. рес. */

 ushort semzcnt; /* число процессов, ожидающих

                    освоб. всех рес. */

};

? sem_pid

PID процесса, который произвел последнюю операцию над семафором.

? sem_semval

Текущее значение семафора.

? sem_semncnt

Число процессов, ожидающих увеличения значения семафора, то есть освобождения ресурсов.

? sem_semzcnt

Число процессов, ожидающих освобождения всех ресурсов.

Данный текст является ознакомительным фрагментом.