Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Билетики.pdf
Скачиваний:
1
Добавлен:
05.06.2025
Размер:
6.66 Mб
Скачать

Пример: pthread_cond_wait в POSIX для ожидания события. 4.​ Сигналы:

Асинхронные уведомления о событиях (например, SIGTERM для завершения процесса).

Пример: Обработка нажатия Ctrl+C в Linux. 5.​ Очереди сообщений:

Асинхронный обмен данными между процессами.

Пример: POSIX mq_send/mq_receive для передачи сообщений. 6.​ Общая память с синхронизацией:

Используется с семафорами/мьютексами для координации доступа. Пример: POSIX shm_open с мьютексами.

7.​ Барьеры:

Синхронизируют выполнение группы потоков до достижения общей точки.

Пример: pthread_barrier_wait в POSIX.

8.​ Глобальные переменные (в пределах одного процесса):

Простейший способ для потоков одного процесса, но не применим для разных процессов.

34. Ситуация состязаний (гонки). Способы предотвращения.

Гонки – ситуация, когда два или более потока обрабатывают разделяемые данные, и конечный результат зависит от соотношения скоростей потоков.

Важным понятием синхронизации потоков является понятие «критической секции» программы. Критическая секция — это часть программы, результат выполнения которой может непредсказуемо меняться, если переменные, относящиеся

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

копределенным критическим данным, при несогласованном изменении которых могут

возникнуть нежелательные эффекты.

Чтобы исключить эффект гонок по отношению к критическим данным,

необходимо обеспечить, чтобы в каждый момент времени в критической секции,

связанной с этими данными, находился только один поток.

Взаимное исключение (Mutual Exclusion, Mutex) — это механизм синхронизации в многопроцессных или многопоточных системах, который

обеспечивает, чтобы только один процесс или поток одновременно имел доступ к общему ресурсу или критической секции кода. Это предотвращает возникновение

гонок (data races) и гарантирует корректность работы с общими данными или ресурсами.это

Для предотвращения можно использовать различные средства IPC (см выше).

35. Способы реализации взаимных исключений: блокирующие переменные, критические секции, семафоры.

Блокирующие переменные

Каждому набору критических данных ставится в соответствие двоичная переменная,

которой поток присваивает значение 0, когда он входит в критическую секцию, и значение 1, когда он ее покидает. Нельзя прерывать поток между выполнением

операций проверки и установки блокирующей переменной.

Критические секции

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

предусматриваются специальные системные вызовы для работы с критическими

секциями.

Семафоры

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

Никакие прерывания во время выполнения примитивов V и Р недопустимы.

В частном случае, когда семафор S может принимать только значения 0 и 1, он превращается в блокирующую переменную, которую по этой причине часто называют двоичным семафором (он же наш любимый мьютекс).

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

Для примера можно привести задачу производителя и потребителя. Имеется

некий буфер размера N. Используя 2 семафора - один блокирует работу источника, если буфер переполнен, второй блокирует работу потребителя, если в буфере пусто.

Первый должен быть инициализирован N, второй 0. ЗАДАЧА ПИСАТЕЛИ И ЧИТАТЕЛИ.

36. Классические задачи синхронизации: «производители-потребители», «проблема обедающих философов», «проблема спящего брадобрея».

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

данным, а неправильная координация может привести к тупикам. Для решения этой

проблемы применяются механизмы синхронизации. Мьютексы используются для

защиты буфера, чтобы только один процесс или поток мог с ним работать в данный

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

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

Официант

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

разрешения официанта — которое не будет получено, пока вилка не будет

освобождена. Предполагается, что философ всегда пытается сначала взять левую вилку, а потом — правую (или наоборот), что упрощает логику. Официант работает, как семафор

Иерархия ресурсов

Другое простое решение достигается путём присвоения частичного порядка ресурсам

(в данном случае вилкам) и установления соглашения, что ресурсы запрашиваются в указанном порядке, а возвращаются в обратном порядке. Кроме того, не должно быть

двух ресурсов, не связанных порядком, используемых одной рабочей единицей.

Пусть ресурсы (вилки) будут пронумерованы от 1 до 5, и каждая рабочая единица

(философ) всегда берёт сначала вилку с наименьшим номером, а потом вилку с

наибольшим номером из двух доступных. Далее, философ кладёт сначала вилку с бо́льшим номером, потом — с меньшим. В этом случае, если четыре из пяти

философов одновременно возьмут вилку с наименьшим номером, на столе останется вилка с наибольшим возможным номером. Таким образом, пятый философ не сможет взять ни одной вилки. Более того, только один философ будет иметь доступ к вилке с

наибольшим номером, так что он сможет есть двумя вилками. Когда он закончит использовать вилки, он в первую очередь положит на стол вилку с бо́льшим номером,

потом — с меньшим, тем самым позволив другому философу взять недостающую вилку и приступить к еде.