Основы программирования в Linux
Основы программирования в Linux читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
Одним из возможных решений проблемы можно считать уже знакомое вам создание файла с помощью флага
O_EXCL
open
Важный шаг вперед в сфере параллельного программирования был сделан, когда голландский специалист в области компьютерных наук Эдсгер Дейкстра (Edsger Dijkstra) предложил идею семафоров. Как уже кратко упоминалось в главе 12, семафор — это специальная переменная, которая принимает только целые положительные значения и с помощью которой программы могут действовать только атомарно. В этой главе мы расширим данное ранее упрощенное определение. Будет более подробно рассказано, как действуют семафоры и как для взаимодействия отдельных процессов применяются функции общего назначения вместо особого случая многопоточных программ, которые рассматривались в главе 12.
Определяя более строго, семафор — это специальная переменная, для которой разрешены только две операции, формально именуемые ожиданием или приостановкой (wait) и оповещением (signal). Поскольку в программировании Linux у приостановки и оповещения уже есть специальные значения, мы будем применять оригинальное обозначение:
□
P
□
V
Эти буквы взяты из голландских слов для приостановки (passeren — проходить, пропускать как в случае контрольной точки перед критической секцией) и для оповещения (vrijgeven — предоставлять или освобождать, как в случае отказа от контроля критической секции). Вы можете встретить термины "вверх" (up) и "вниз" (down), применяемые в отношении семафоров по аналогии с использованием сигнальных флажков.
Описание семафора
Простейший семафор — это переменная, способная принимать только значения 0 и 1, бинарный или двоичный семафор. Это наиболее распространенный вид семафора. Семафоры, принимающие много положительных значений, называют семафорами общего вида. В оставшейся части главы мы сосредоточимся на двоичных семафорах.
Определения операций
P
V
sv
Таблица 14.1
Операция | Описание |
---|---|
Р(sv) | Если sv |
V(sv) | Если какой-то другой процесс был приостановлен в ожидании семафора sv sv |
Другой способ описания семафора — считать, что переменная
sv
true
P(sv)
false
V(sv)
true
false
Теоретический пример
С помощью простого теоретического примера можно посмотреть, как действует семафор. Предположим, что у вас есть два процесса: proc1 и proc2, оба нуждающиеся в некоторый момент выполнения в монопольном доступе к базе данных. Вы определяете один бинарный семафор
sv
Оба процесса совместно используют переменную-семафор
sv
P(sv)
P(sv)
V(sv)
Требуемый псевдокод у обоих процессов идентичен:
semaphore sv = 1;
loop forever {
P(sv);
critical code section;
V(sv);
noncritical code section;
}
Код на удивление прост, потому что определение операций
P
V
Рис. 14.1
На рис. 14.1 показана схема действующих операций
P
V
Реализация семафоров в Linux
Теперь, когда вы увидели, что такое семафоры и как они действуют в теории, можно рассмотреть, как их свойства реализованы в ОС Linux. Интерфейс тщательно проработан и предлагает гораздо больше возможностей, чем обычно требуется. Все функции семафоров в Linux оперируют массивами семафоров общего вида, а не одним двоичным семафором. На первый взгляд кажется, что такой подход все усложняет, но если процесс нуждается в блокировке нескольких ресурсов, способность оперировать массивом семафоров — большое подспорье. В этой главе мы сосредоточимся на применении одиночных семафоров, поскольку в большинстве случаев это все, что вам нужно.
Далее приведены объявления функций семафоров:
<b>#include <sys/sem.h></b>
<b>int semctl(int sem_id, int sem_num, int command, ...);</b>
<b>int semget(key_t key, int num_sems, int sem_flags);</b>
<b>int semop(int sem_id, struct sembuf *sem_ops, size_t num_sem_ops);</b>