
- •КУрсовая работа
- •1 Критические секции, интервалы, ресурсы
- •1.1 Введение
- •1.2 Понятие критической секции и интервала
- •1.3 Работа с критическими секциями
- •1.4 Вывод
- •2 Задача об обедающих философах
- •2.1 Постановка задачи
- •2.2 Сеть Петри
- •2.3 Листинг процедур, обеспечивающих решение задачи
- •2.4 Вывод
- •Список используемых источников
Министерство образования и науки Российской Федерации
Федеральное государственное бюджетное образовательное учреждение
высшего профессионального образования «Магнитогорский государственный технический университет им. Г.И. Носова»
Кафедра вычислительной техники и прикладной математики
КУрсовая работа
по дисциплине: «Теория вычислительных процессов»
на тему: «Критические секции, интервалы, ресурсы. Решение задачи об обедающих философах»
Выполнил: |
студент группы АВ-10 Головачев А.В. |
Проверила: |
к.т.н., доц. Кочержинская Ю.В. |
Магнитогорск, 2012
Содержание
1 Критические секции, интервалы, ресурсы 3
1.1 Введение 3
1.2 Понятие критической секции и интервала 3
1.3 Работа с критическими секциями 6
1.4 Вывод 9
2 Задача об обедающих философах 10
2.1 Постановка задачи 10
2.2 Сеть Петри 10
2.3 Листинг процедур, обеспечивающих решение задачи 11
2.4 Вывод 19
Список используемых источников 20
1 Критические секции, интервалы, ресурсы
1.1 Введение
Функционирование мультипрограммной вычислительной системы характерно тем, что в ее среде одновременно развиваются несколько параллельных потоков. В своем развитии параллельные потоки часто используют одни и те же ресурсы системы, т. е. разделяют их. Часть таких разделяемых ресурсов требуют только последовательного использования со стороны потоков, т. е. в каждый момент времени только один поток может использовать разделяемый ресурс. Такие ресурсы называются критическими. Для того чтобы обеспечить последовательное использование критических ресурсов необходимо синхронизировать доступ к ним.
Задача синхронизации, в общем случае, состоит в следующем. Если несколько потоков хотят пользоваться критическим ресурсом в режиме разделения, им следует синхронизировать свои действия таким образом, чтобы такой ресурс всегда находился в распоряжении не более чем одного из них. Если один поток пользуется в данный момент критическим ресурсом, то все остальные потоки, которым нужен этот ресурс, должны получить отказ в доступе и ждать, пока он не освободится. Если в системе не предусмотрена защита от одновременного доступа потоков к критическим ресурсам, в ней могут возникать ошибки, которые трудно обнаружить и исправить. Основной причиной возникновения таких ошибок является то, что потоки развиваются с разными скоростями, прием эти скорости самим потокам неподвластны и неизвестны друг другу. [1]
Таким образом, при организации различного рода взаимодействующих потоков необходимо решать проблему корректного доступа к общим переменным, которые идентифицируют критические ресурсы с программной точки зрения.
1.2 Понятие критической секции и интервала
Те места в программах, в которых происходит обращение к критическим ресурсам, называются критическими интервалами или критическими секциями (critical section). Решение этой проблемы в операционной системе Windows заключается в организации такого доступа к критическому ресурсу, когда только одному потоку разрешается входить в свою критическую секцию.
Когда какой-либо поток находится в своем критическом интервале, другие потоки могут продолжать свое выполнение, но без входа в свои критические секции. Взаимное исключение необходимо только в том случае, когда потоки обращаются к разделяемым, общим данным. Если же потоки выполняют операции, которые не приводят к конфликтным ситуациям, они должны иметь возможность выполняться параллельно. Когда поток выходит из своего критического интервала, то одному из остальных потоков, ожидающих входа в свои критические секции, должно быть разрешено продолжить выполнение, т. е. разрешено войти в свой критический интервал.
Критические секции – это объекты, используемые для блокировки доступа всех потоков процесса, кроме одного, к некоторым важным данным в один момент времени. Например, имеется переменная m_pObject и несколько потоков, вызывающих методы объекта, на который ссылается m_pObject, причем эта переменная может изменять свое значение время от времени. Предположим, имеется следующий код:
// Поток №1 void Proc1() { if (m_pObject) m_pObject->SomeMethod(); }
// Поток №2 void Proc2(IObject *pNewObject) { if (m_pObject) delete m_pObject; m_pObject = pNewobject; } |
В данном примере имеется потенциальная опасность вызова m_pObject->SomeMethod() после того, как объект был уничтожен при помощи delete m_pObject. Дело в том, что в системах с вытесняющей многозадачностью выполнение любого потока процесса может прерваться в самый неподходящий для него момент времени, и начнет выполняться совершенно другой поток. В данном примере неподходящим моментом будет тот, в котором поток №1 уже проверил m_pObject, но еще не успел вызвать SomeMethod(). Выполнение потока №1 прервалось, и начал исполняться поток №2. Причем поток №2 успел вызвать деструктор объекта. Если поток №1 получит процессорное время и вызовет SomeMethod() у уже несуществующего объекта, случится ошибка.
Именно в таких ситуациях используются критические секции. Перепишем наш пример.
// Поток №1 void Proc1() { ::EnterCriticalSection(&m_lockObject); if (m_pObject) m_pObject->SomeMethod(); ::LeaveCriticalSection(&m_lockObject); }
// Поток №2 void Proc2(IObject *pNewObject) { ::EnterCriticalSection(&m_lockObject); if (m_pObject) delete m_pObject; m_pObject = pNewobject; ::LeaveCriticalSection(&m_lockObject); } |
Код, помещенный между ::EnterCriticalSection() и ::LeaveCriticalSection() с одной и той же критической секцией в качестве параметра, никогда не будет выполняться параллельно. Это означает, что если поток №1 успел "захватить" критическую секцию m_lockObject, то при попытке потока №2 заполучить эту же критическую секцию в свое единоличное пользование, его выполнение будет приостановлено до тех пор, пока поток №1 не "отпустит" m_lockObject при помощи вызова ::LeaveCriticalSection(). И наоборот, если поток №2 успел раньше потока №1, то тот "подождет", прежде чем начнет работу с m_pObject.