Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Критические ресурсы и секции.docx
Скачиваний:
0
Добавлен:
01.04.2025
Размер:
100.37 Кб
Скачать

Министерство образования и науки Российской Федерации

Федеральное государственное бюджетное образовательное учреждение

высшего профессионального образования «Магнитогорский государственный технический университет им. Г.И. Носова»

Кафедра вычислительной техники и прикладной математики

КУрсовая работа

по дисциплине: «Теория вычислительных процессов»

на тему: «Критические секции, интервалы, ресурсы. Решение задачи об обедающих философах»

Выполнил:

студент группы АВ-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.