Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Демкин_Экзамен.doc
Скачиваний:
10
Добавлен:
26.11.2018
Размер:
1.2 Mб
Скачать
  1. Назовите и кратко опишите существующие способы синхронизации многопоточных приложений.

Семафо́р — объект, позволяющий войти в заданный участок кода не более чем n потокам. Определение введено Эдсгером Дейкстрой.Содержание [убрать]

Семафор — это объект, с которым можно выполнить три операции.

init(n):

счётчик := n

enter():

ждать пока счётчик станет больше 0; после этого уменьшить счётчик на единицу.

leave():

увеличить счётчик на единицу.

Предположим, что есть такой участок кода:

semaphore.init(5);

void DoSomething( void )

{

semaphore.enter();

semaphore.leave();

}

Тогда не более пяти потоков могут одновременно выполнять функцию DoSomething().

В более сложных семафорах может использоваться очередь; при этом потоки, ожидающие освобождения семафора, будут проходить через семафор именно в том порядке, в котором они вызывали enter().

Применение семафоров

Вот некоторые из проблем, которые могут решать семафоры.

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

  1. поочерёдный доступ к критическому ресурсу (важному ресурсу, для которого невозможен одновременный доступ).

Монитор — в языках программирования, высокоуровневый механизм взаимодействия и синхронизации процессов, обеспечивающий доступ к неразделяемым ресурсам.[1] Подход к синхронизации двух или более компьютерных задач, использующих общий ресурс, обычно аппаратуру или набор переменных.

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

Альтернативой мониторам является транзакционная память

Транзакционная память, позволяет работать с данными, при помощи транзакций, аналогичных транзакциям баз данных. Транзакции выполняются таким образом, как будто текущая транзакция это единственная операция над текущими данными. При завершении транзакции, смотрится не было ли конфликтов с другими транзакциями. Если их не было (наиболее вероятный вариант), изменение принимаются, если нет, транзацкия повторяется еще раз. В программах, в которых имеется большое количество потоков, работающих с различными областями памяти, такая схема будет работать очень хорошо: конфликты будут редки, а степень параллельности будет высокой. К сожалению, есть и некоторые недостатки: в транзакционных блокак желательно не вызывать код имеющий побочные эффекты: ввод/вывод, рисование на экране, итп.

В настоящий момент существует достаточно большое количество библиотек (например, MultiVerse для Java), которые позволяют использовать данный подход в существующих языка программирования, а тажке некоторые языки (Fortress, Clojure), которые поддерживают транзакционную память напрямую.

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