Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

syncro

.pdf
Скачиваний:
7
Добавлен:
21.05.2015
Размер:
328.14 Кб
Скачать

СИНХРОНИЗАЦИЯ

ПАРАЛЛЕЛЬНО

ВЫПОЛНЯЕМЫХ

ЗАДАЧ

В этой главе...

5.1.Координирование порядка выполнения потоков

5.2.Синхронизация доступа к данным

5.3.Что такое семафоры

5.4.Объектно-ориентированный подход к синхронизации

5.5.Резюме

5

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

Ноберт Винер (Norbert Wiener), Кибернетика

Во всех компьютерных системах ресурсы ограничены. Ведь любой объем памя ти конечен, как и количество устройств ввода вывода, портов, аппаратных прерываний и процессоров. Если в среде ограниченных аппаратных ресурсов

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

5.1. Координация порядка выполнения потоков 185

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

Синхронизация также необходима для координации порядка выполнения парал лельных задач. Примером может служить модель “изготовитель потребитель”, кото рая рассмотрена в главе 4. “Изготовитель” обязательно начинает выполняться до “потребителя”, но не обязательно завершается до него. Подобные задачи нуждаются в синхронизации. Синхронизация данных (синхронизация доступа к данным) и задач (синхронизация последовательностей инструкций) — два типа синхронизации, которые необходимо обеспечить при выполнении нескольких параллельных задач.

5.1. Координация порядка выполнения потоков

Предположим, у нас есть три параллельно выполняющихся потока — A, B и C. Все они участвуют в обработке списка. Список необходимо отсортировать, выпол нить в нем операции поиска и вывода результатов. Каждому потоку назначается от дельная задача. Так, поток A должен отобразить результаты поиска, B — отсортиро вать список, а C — провести поиск. Сначала список необходимо отсортировать, за тем выполнить несколько параллельных операций поиска, а уж потом отобразить результаты. Если задачи, выполняемые потоками, не синхронизировать надлежа щим образом, то поток A может попытаться отобразить еще не сгенерированные результаты, что нарушит постусловие, или выходное условие (postcondition), про цесса. Предусловием, или входным условием (precondition), здесь является необхо димость получения отсортированного списка до выполнения в нем поиска. Поиск

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

висполнение постусловия и предусловия логических процессов. UML диаграмма видов деятельности для этого процесса представлена на рис. 5.1.

Сначала поток B должен отсортировать список, затем эстафета управления переда ется “многоканальному” поиску, порождаемому потоком C. И только после завершения поисковых работ по всем направлениям поток A отображает результаты поиска.

5.1.1.Взаимоотношения между синхронизируемыми задачами

Существует четыре основных типа отношений синхронизации между любыми двумя потоками в одном процессе или между любыми двумя процессами в одном при ложении: старт старт (СС), финиш старт (ФС), старт финиш (СФ) и финиш финиш (ФФ). С помощью этих основных типов отношений можно охарактеризовать коорди нацию задач между потоками и процессами. UML диаграмма видов деятельности для каждого типа отношений синхронизации показана на рис. 5.2.

186 Глава 5. Синхронизация параллельно выполняемых задач

Поток A

Поток B

Поток C

[Отсортированный

список]

[Неотсортированный

список]

Сортировка

списка

Поиск значения 1 Поиск значения 2 ... Поиск значения n

Отображение

результатов

поиска

Рис. 5.1. Диаграмма видов деятельности для задач сортировки списка, поиска и отображения результатов поиска

5.1.2. Отношения типа старт-старт (СС)

В отношениях синхронизации типа старт старт одна задача не может начаться до тех пор, пока не начнется другая. Одна задача может начаться раньше другой, но не позже. Предположим, у нас есть программа, которая реализует инкарнацию (воплощение). Инкарнация “материализуется” в виде говорящей головы, созданной, разумеется, компьютерной программой. Инкарнация обеспечивает своего рода “одушевление” программ. Программа, которая реализует “одушевление”, имеет не сколько потоков. Здесь нас в первую очередь интересует поток A, который “отвечает” за

5.1. Координация порядка выполнения потоков 187

анимацию результата, и поток B, который управляет звуком, или голосом, говорящей головы. Мы хотим создать иллюзию синхронизации звука и движений рта. В идеале они должны происходить абсолютно одновременно. При наличии нескольких процессоров оба потока могут начинаться одновременно. Эти потоки связаны отношением типа старт старт. В соответствии с условиями временной синхронизации допускается, чтобы поток A начинался немного раньше потока B (именно немного — иначе будет нарушена иллюзия одновременности), но поток B не может начаться раньше потока A. Голос должен ожидать анимацию, а не наоборот. Совершенно нежелательно услышать голос до того, как зашевелятся губы (если это не синхронное озвучивание).

СТАРТ-СТАРТ

 

 

 

 

 

ФИНИШ-ФИНИШ

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Поток A

 

 

Поток B

 

 

 

Поток A

 

 

 

 

Поток B

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<< сигнал >>

 

 

 

Поток B заблокирован

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Поток A

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

заблокирован

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<< сигнал >>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ФИНИШ-СТАРТ

 

 

 

 

 

 

СТАРТ-ФИНИШ

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Поток A

 

 

 

Поток B

 

 

 

Поток A

 

 

Поток B

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Поток B заблокирован

 

 

Поток A

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

заблокирован

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<< сигнал >>

 

 

 

 

 

<< сигнал >>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 5.2. Возможные отношения синхронизации между задачами A и B

5.1.3. Отношения типа финиш-старт (ФС)

В отношениях синхронизации типа финиш старт задача A не может завершиться до тех пор, пока не начнется задача B. Этот тип отношений типичен для родительско сыновних процессов. Родительский процесс не может завершить выполнение неко торых операций до тех пор, пока не будет сгенерирован сыновний процесс или пока не будет получена обратная связь от сыновнего процесса, который начал выполне ние. Сыновний процесс, “просигналивший” родителю или предоставивший ему необ ходимую информацию, продолжает выполняться, а родительский процесс после это го может завершиться.

188 Глава 5. Синхронизация параллельно выполняемых задач

5.1.4. Отношения типа старт-финиш (СФ)

Отношения типа старт финиш можно считать обратным вариантом отношений типа финиш старт. В отношениях синхронизации типа старт финиш одна задача не может начаться до тех пор, пока не завершится другая. Задача A не может начать вы полнение до тех пор, пока задача B не финиширует или не завершит выполнение оп ределенной операции. Если процесс A считывает данные из канала, связанного с процессом B, то процесс B должен записать данные в канал, прежде чем процесс A начнет считывать из него данные. Процесс B должен завершить по крайней мере одну операцию, записав в канал один элемент, прежде чем начнет действовать процесс A. Потоки, действующие по принципу “производитель потребитель”, — это еще один пример взаимоотношений типа финиш старт. Потоки, обслуживающие сортировку и поиск элементов в списке (см. рис. 5.1), также демонстрируют этот тип отношений. Прежде чем начнут действовать потоки, реализующие поиск, должен завершить свою работу поток сортировки. Во всех этих случаях один поток или процесс должен за вершить свою операцию, прежде чем другой попытается выполнить свою задачу. Ес ли работа потоков не будет скоординирована, глобальная цель потока, процесса или приложения достигнута не будет или же будут получены ошибочные результаты.

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

5.1.5. Отношения типа финиш-финиш (ФФ)

В отношениях синхронизации типа финиш финиш одна задача не может завер шиться до тех пор, пока не завершится другая, т.е. задача A не может финишировать до задачи B. Этот тип отношений можно применить к описанию отношений между родительскими и сыновними процессами, которые рассматривались в главе 3. Роди тельский процесс должен ожидать до тех пор, пока не завершатся все сыновние про цессы, и только потом сможет завершиться сам. Если описанная последовательность нарушится, и родительский процесс финиширует раньше своих потомков, то эти за вершенные сыновние процессы перейдут в зомбированное состояние. Родительские процессы не должны завершаться (выходить из системы в данном случае) до тех пор, пока не выполнятся до конца их сыновние процессы. Для родительских процессов это достигается за счет вызова функции wait() для каждого из своих сыновних про цессов либо ожидания деблокировки (освобождения) мьютекса или условной пере менной, что может быть осуществлено сыновними потоками. Еще одним примером отношений типа финиш финиш может служить модель “управляющий рабочий”. За дача управляющего потока — делегировать работу рабочим потокам. Для управляюще го крайне нежелательно завершить работу раньше рабочих. В этом случае не были бы обработаны новые запросы к системе, не имели работы существующие потоки и не создавались новые. Если управляющий поток является основным потоком процесса, и он завершается, то процесс должен завершиться вместе со всеми рабочими потока

5.2. Синхронизация доступа к данным 189

ми. Если в модели равноправных потоков поток A динамически создает объект, пере даваемый потоку B, и поток A затем завершается, то вместе с ним разрушается и соз данный им объект. Если это произойдет до того, как поток B получит возможность использовать этот объект, возникнет ошибка сегментации или нарушится доступ к данным. Чтобы предотвратить возникновение этого типа ошибок, завершение по токов синхронизируется с помощью функции pthread_join(). Обращение к этой функции заставляет вызывающий поток ожидать до тех пор, пока не финиширует за данный поток. Таким образом и создается синхронизация типа финиш финиш.

5.2. Синхронизация доступа к данным

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

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

Синхронизация данных необходима для управления состоянием “гонок”, а также для того, чтобы позволить параллельным потокам или процессам безопасно получить доступ к блоку памяти. Синхронизация данных позволяет управлять считыванием

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

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

5.2.1. Модель PRAM

Модель PRAM (Parallel Random Access Machine — машина с параллельным произ вольным доступом) — это упрощенная модель с N процессорами, обозначаемыми P1, P2, P3, ... Pn, которые разделяют одну глобальную память. Все процессоры одновре менно получают доступ для чтения и записи к совместно используемой глобальной

190 Глава 5. Синхронизация параллельно выполняемых задач

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

Рис. 5.3. Память, разделяемая между потоками и процессами

5.2. Синхронизация доступа к данным 191

5.2.1.1. Параллельный и исключающий доступ к памяти

Алгоритмы параллельного и исключающего чтения и записи можно скомбиниро вать и получить следующие типы объединенных алгоритмов, которые можно реали зовать для организации доступа к данным:

исключающее чтение и исключающая запись (exclusive read and exclusive write — EREW);

параллельное чтение и исключающая запись (concurrent read and exclusive write — CREW);

исключающее чтение и параллельная запись (exclusive read and concurrent write — ERCW);

параллельное чтение и параллельная запись (concurrent read and concurrent write — CRCW).

Эти алгоритмы можно рассматривать как стратегии доступа, реализуемые задача ми, которые совместно используют данные (рис. 5.4). Алгоритм EREW подразумевает последовательный доступ к разделяемой памяти, т.е. к общей памяти в любой момент времени может получить доступ только одна задача. Примером стратегии доступа EREW может служить вариант реализации модели потоков “производитель потребитель”, рассмотренный в главе 4. Доступ к очереди, содержащей имена фай лов, может быть ограничен исключающей записью “изготовителя” и исключающим чтением “потребителя”. В любой момент времени доступ к очереди может быть раз решен только для одной задачи. Стратегия CREW позволяет множественный доступ для чтения общей памяти и исключающий доступ для записи в нее данных. Это озна чает отсутствие ограничений на количество задач, которые могут одновременно чи тать разделяемую память, но записывать в нее данные может только одна задача. При этом параллельное чтение может происходить одновременно с записью данных в об щую память. При использовании этой стратегии доступа все читающие задачи могут прочитать различные значения, поскольку во время чтения значения из общей памя ти записывающая задача может его модифицировать. Стратегия доступа ERCW — это прямая противоположность стратегии CREW. При использовании стратегии ERCW разрешены параллельные записи в общую память, но лишь одна задача может читать ее в любой момент времени. Стратегия доступа CRCW позволяет множеству задач вы полнять параллельное чтение и запись.

Для этих четырех типов алгоритмов требуются различные уровни и типы синхро низации. Их диапазон довольно широк: от стратегии доступа, реализация которой требует минимальной синхронизации, до стратегии доступа, реализация которой требует максимальной синхронизации. Наша задача — реализовать эти стратегии, поддерживая целостность данных и удовлетворительную производительность систе мы. EREW — самая простая для реализации стратегия, поскольку она предполагает, по сути, только последовательную обработку. На первый взгляд самой простой может показаться стратегия CRCW, но она таит в себе массу трудностей. А ведь это только кажется, что если к памяти можно получить доступ без ограничений, то в ней и речь не идет о какой бы то ни было стратегии. Все как раз наоборот: CRCW — самая труд ная для реализации стратегия, которая требует максимальной синхронизации.

192 Глава 5. Синхронизация параллельно выполняемых задач

EREW (исключающее чтение и исключающая запись)

 

 

 

 

 

 

 

 

 

блокируется

 

 

 

 

Запись

 

 

Чтение

 

 

 

Поток А

Разделяемая

Поток В

 

 

 

 

 

 

память

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Запись

 

 

Чтение

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Поток А

Разделяемая

 

Поток В

 

 

 

 

 

 

память

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

ERCW (исключающее чтение и параллельная запись)

 

 

 

 

 

 

 

 

 

 

Чтение

 

 

 

 

 

Запись

 

 

 

 

 

 

 

 

Поток А

 

 

 

 

 

 

 

 

 

 

Разделяемая

 

 

 

 

 

 

 

Поток В

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

память

 

 

 

 

 

 

 

 

 

 

Поток С

Запись

 

 

 

Чтение

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Поток D

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

CREW (параллельное чтение и исключающая запись)

 

 

 

 

 

 

 

 

 

Чтение

 

 

 

 

 

Запись

 

 

 

 

 

 

 

 

 

 

Поток А

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Поток B

 

 

 

 

 

 

Разделяемая

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

память

 

 

 

 

 

 

 

 

 

 

Поток С

Запись

 

 

 

 

Чтение

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Поток D

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

CRCW (параллельное чтение и параллельная запись)

Поток А

Запись

 

 

Чтение

 

Поток B

 

 

Разделяемая

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

память

 

 

 

Поток С

Запись

 

 

Чтение

Поток D

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Рис. 5.4. Стратегии доступа EREW, CREW, ERCW и CRCW

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]