10.14. Реализация с использованием FIFO
10.14. Реализация с использованием FIFO
Займемся реализацией именованных семафоров Posix с помощью каналов FIFO. Именованный семафор реализуется как канал FIFO с конкретным именем. Неотрицательное количество байтов в канале соответствует текущему значению семафора. Функция sem_post помещает 1 байт в канал, a sem_wait считывает его оттуда (приостанавливая выполнение процесса, если канал пуст, а именно этого мы и хотим). Функция sem_open создает канал FIFO, если указан флаг O_CREAT; открывает его дважды (один раз на запись, другой — на чтение) и при создании нового канала FIFO помещает в него некоторое количество байтов, указанное в качестве начального значения.
ПРИМЕЧАНИЕ
Этот и последующие разделы данной главы содержат усложненный материал, который можно при первом чтении пропустить.
Приведем текст нашего заголовочного файла semaphore.h, определяющего фундаментальный тип sem_t (листинг 10.21).
Листинг 10.21. Заголовочный файл semaphore.h
//my_pxsem_fifo/semaphore.h
1 /* фундаментальный тип */
2 typedef struct {
3 int sem_fd[2]; /* два дескриптора fd: [0] для чтения, [1] для записи */
4 int sem_magic; /* магическое число */
5 } mysem_t;
6 #define SEM_MAGIC 0x89674523
7 #ifdef SEM_FAILED
8 #undef SEM_FAILED
9 #define SEM_FAILED ((mysem_t *)(-1)) /* чтобы компилятор не выдавал предупреждений*/
10 #endif
Тип данных sem_t
1-5 Новая структура данных содержит два дескриптора, один из которых предназначен для чтения из FIFO, а другой — для записи. Для единообразия мы храним оба дескриптора в массиве из двух элементов, в котором первый дескриптор всегда открыт на чтение, а второй — на запись.
Поле sem_magiс содержит значение SEM_MAGIC, если структура проинициализирована. Это значение проверяется всеми функциями, которым передается указатель на тип sem_t, чтобы гарантировать, что передан был действительно указатель на заранее инициализированную структуру, а не на произвольную область памяти. При закрытии семафора этому полю присваивается значение 0. Этот метод хотя и не совершенен, но дает возможность обнаружить некоторые ошибки при написании программ.
Данный текст является ознакомительным фрагментом.