Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
03-21-12 Параллельные вычисления.DOC
Скачиваний:
4
Добавлен:
23.08.2019
Размер:
322.56 Кб
Скачать

Лекція №7 Паралельні обчислення: взаємовиключення і багатозадачність

  1. Принципи паралельних обчислень

    1. Участь операційної системи

    2. Взаємодія процесів

    3. Вимоги до взаємних виключень

  2. Взаємовиключення: програмний підхід

    1. Алгоритм Деккера

    2. Алгоритм Петерсена

  3. Взаємовиключення: апаратна підтримка

    1. Інструкція перевірки та встановлення значення

    2. Інструкція обміну

    3. Властивості підходу, що використовує машинні інструкції

Основные вопросы, на которые сосредоточивается внимание разработчиков ОС, связанное с управлением процессами и потоками:

Многозадачность: управления множеством процессов в однопроцессорной системе.

Многопроцессорность: управление множеством процессов в многопроцессорной системе.

Распределенные вычисления: управление множеством процессов, выполняемых в распределенной вычислительной системе с множеством компьютеров (кластеры).

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

7.1. Принципы параллельных вычислений

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

7.1.1. Участие операционной системы

При наличии параллельных вычислений перечислим такие вопросы, которые возникают при создании и управлении ОС.

1. ОС должна отслеживать разные активные процессы. Это выполняется с помощью блоков управления процессов.

2. ОС должна распределять и освобождать разные ресурсы для каждого активного процесса, а именно:

- Процессорное время: это функция планирования;

- Память: большинство ОС используют схему виртуальной памяти;

- Файловая система;

- Устройства ввода-вывода.

3. ОС должна защищать данные и ресурсы каждого процесса от неумышленного влияния других процессов.

4. Результат работы процесса не должен зависеть от скорости его выполнения по отношению к другим процессам, которые выполняются параллельно.

7.1.2. Взаимодействие процессов

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

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

Рассмотрим случай, когда два клиента А и В совместно пользуются одним и тем же счетом. Пусть на счете было 100 грн. Клиент А хочет добавить до счета 200 грн, а клиент В – 100 грн. Поток ТА соответствует клиенту А, а ТВ – клиенту В. Рассмотрим такую последовательность операций (Вариант 1).

  1. Поток ТА считывает Total_Amount, равный 100.

  2. Поток ТВ считывает Total_Amount, равный 100.

  3. Поток ТА увеличивает Total_Amount на 200 и сохраняет его в глобальной памяти (Total_Amount, равный 300).

  4. Поток ТВ увеличивает Total_Amount на 100 и сохраняет его в глобальной памяти. В результате в Total_Amount будет 200 грн, вместо 400 грн.

Теперь рассмотрим другую последовательность операций (Вариант 2).

  1. Поток ТА считывает Total_Amount, равный 100, увеличивает его на 200 и записывает в глобальную память.

  2. Поток ТВ считывает Total_Amount, уже равную 300, увеличивает его на 100, и записывает в глобальную память.

В результате оба взноса зарегистрированы успешно.

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

Попытки решения подобных проблем вызвали необходимость синхронизации процессов. То есть, основное назначение синхронизации – это необходимость обеспечения защиты данных от влияния других потоков.

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

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

В случае блокирования проверяют, не было ли оно уже сделано другими процессами (потоками), а если это так, то этот процесс переходит в ожидание, иначе он совершает блокирование состояния и входит в критическую секцию. После выхода из критической секции процесс снимает блокирование. Так реализуется взаимное исключение, отсюда походит еще одно название блокирования – мьютекс (mutex, сокращение от mutual exclusion). В общем случае мьютексом называют синхронизационный примитив, который не допускает выполнения некоторого фрагмента кода больше как одним процессом. Обычно мьютекс - это переменная, которая может находиться в одном из двух состояний: блокированном (0) или неблокированном состоянии (≠ 0). Мьютекс можно рассматривать как упрощенный семафор, который мы будем рассматривать позже.

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

При реализации взаимных исключений возникают дополнительно две проблемы. Одна из них - взаимное блокирование. Рассмотрим два процесса Р1 и Р2 и два ресурса R1 и R2. Предположим, что каждому процессу для выполнения некоторых функций нужен доступ к обоим ресурсам. При этом возможная ситуация: ОС выделяет ресурс R1 процессу Р2, а ресурс R2 – процессу Р1. Процессы будут взаимно заблокированы.

Последняя проблема – голодание. Предположим, что мы имеем три процесса Р1, Р2, Р3, каждому из которых нужный доступ к ресурсу R. Предположим Р1 удерживает ресурс R, а Р2 и Р3 приостановленные в ожидании освобождения ресурса. После выхода Р1 из критического раздела доступ к ресурсу получает Р2 или Р3. Предположим ОС предоставила доступ к ресурсу R процессу Р3. Пока он работает с ресурсом, доступ к ресурсу вновь требуется процессу Р1. В результате может произойти, что ОС предоставит R снова процессу Р1. Потом доступ может снова понадобиться Р3. Таким образом, возможная ситуация, когда процесс Р2 никогда не получит ресурс R.

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

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