
- •5. Взаимодействие и синхронизация процессов
- •5.1. Взаимодействие процессов (Лекция 9)
- •5.1.1. Способы взаимодействия процессов
- •5.1.1.1. Проблема синхронизации
- •5.1.1.2. Критические секции, средства коммуникации процессов
- •5.1.1.3. Способы взаимодействия процессов, понятия взаимного исключения, взаимной блокировки, голодания процессов
- •5.1.2. Взаимные исключения
- •5.1.2.1. Требования к взаимным исключениям
- •5.1.2.2. Алгоритмы Деккера и Петерсона реализации взаимного исключения
- •5.2. Семафоры и другие средства синхронизации (Лекция 10)
- •5.2.1. Синхронизация задач с помощью семафоров
- •5.2.1.1. Семафоры Дейкстры
- •5.2.1.2. Условная синхронизация с помощью семафоров
- •5.2.1.3. Планирование очереди процессов, ожидающих у семафора
- •5.2.2. Другие средства синхронизации: счётчики событий, секвенсоры, мониторы, передача сообщений
- •5.2.2.1. Счетчики событий и секвенсоры
- •5.2.2.2. Объекты синхронизации, регламентированные posix
- •5.2.2.3. Мониторы Хоара
- •5.2.2.4. Передача сообщений
- •5.3. Классические проблемы межпроцессного взаимодействия (Лекция 11)
- •5.3.1. Проблема "обедающих философов"
- •5.3.1.1. Описание проблемы "обедающих философов"
- •5.3.1.2. Решение (алгоритм) проблемы "обедающих философов"
- •5.3.2. Проблема "спящего брадобрея" (задача о парикмахерской)
- •5.3.2.1. Описание задачи о парикмахерской
- •5.3.2.2. Решение (алгоритм) задачи о парикмахерской
- •5.3.3. Задача "читателей и писателей"
- •5.3.3.1. Описание задачи читателей и писателей
- •5.3.3.2. Решение (алгоритм) задачи читателей и писателей
- •5.4. Взаимоблокировки (Лекция 12)
- •5.4.1. Возникновение взаимоблокировок
- •5.4.1.1. Проблема взаимоблокировок
- •5.4.2. Устранение взаимоблокировок
- •5.4.2.1. Запрещение запуска процесса
- •5.4.2.2. Запрет выделения ресурса
- •5.4.3. Обнаружение взаимоблокировок
- •5.4.3.1. Алгоритм обнаружения взаимоблокировок
- •5.4.3.2. Действия, выполняемые после обнаружения взаимоблокировки
5.2.2.2. Объекты синхронизации, регламентированные posix
В стандарте POSIX 1003.4a (pthread) определены средства синхронизации потоков. Для обеспечения доступа к объектам синхронизации используется дескриптор, возвращаемый системой при создании этого объекта. С каждым объектом синхронизации связан дополнительный объект – набор атрибутов. Для потока такой объект содержит информацию о наследовании атрибутов, планировании, политике и приоритете планирования, размере стека и сторожевом размере стека[сторожевая резервная область стека, наличие которой помогает предотвратить или выявить переполнение стека].
Конкретная реализация стандарта pthread – DECthreads – исполнительная библиотека поддержки многопоточного выполнения дляOSF/1 от компанииDEC.
Потоки POSIX могут использовать дополнительную операцию pthread_join, которая блокирует вызывающий поток до тех пор, пока указанный поток не завершил работу. Предусмотрено два объекта синхронизации: мьютекс, условная переменная.
Мьютекс – двоичный семафор, обеспечивает взаимное исключение. Перед тем, как обратиться к ресурсу, защищенному мьютексом, поток блокирует его, а закончив работу – снимает блокировку. Если мьютекс уже заблокирован, поток либо ждет, либо продолжает некоторые другие действия, в зависимости от того, как была вызвана функция попытки блокирования.
Мьютекс создается вызовом pthread_mutex_init(), в котором можно задать атрибуты, включая следующие типы мьютекса:
1) быстрый (по умолчанию) – блокируется потоком только один раз; если поток попытается заблокировать его еще раз без предварительного разблокирования, возникнет взаимоблокировка потока с самим собой: он будет заблокирован до тех пор, пока сам не разблокирует мьютекс, чего он сделать не сможет.
2) рекурсивный – может быть заблокирован потоком более одного раза. Полезен в тех случаях, когда требуется рекурсивный вызов своей же программы.
3) нерекурсивный – подобно быстрому мьютексу может быть заблокирован только один раз, после чего при попытке блокирования будет возвращаться ошибка. Если другой поток попытается разблокировать данный мьютекс, он тоже получит ошибку. Это средство для отладки программ, впоследствии рекурсивный мьютекс заменяется быстрым.
Условная переменная используется совместно с мьютексом и позволяет потоку дождаться перехода общих данных в заданное состояние, определяемое логическим выражением – предикатом.
Условные переменные используются для крупномасштабных задач, где поток может ожидать выполнения определенного условия в течение относительно длительного времени. Мьютексы, наоборот, используется для мелкоструктурной синхронизации и блокируются на короткие промежутки.
Совместное использование мьютекса и условной переменной: поток блокирует мьютекс, связанный с общими данными и проверяет, находятся ли данные в нужном состоянии. Если нет, он останавливается и ждет возле условной переменной, а мьютекс освобождает. Это важно, т.к. другой поток должен иметь доступ к общим данным для приведения их в нужное состояние. Необходимо, чтобы этот другой поток пробудил ожидающий с помощью сигнализирующего вызова условной переменной. Если около нее ждет несколько потоков, освобождается только один. При этом пробудившийся потоком первым делом снова блокирует мьютекс.