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

Синхронизация потоков без использования объектов синхронизации.

Пусть есть 2 потока. Поток 1 синхронизирует себя завершением какой-либо задачи в другом потоке, постоянно просматривая значения некоторой переменной, доступной из обоих потоков.

f:=false

вычисления

создание двух потоков

f:=true

нет

да

дальнейшая работа

Существуют проблемы.

  1. Первый поток никогда не впадает в «спячку». Он тратит время процессора на проверки.

  2. Булева переменная f никогда не примет значения true.

Вывод: синхронизация необходима.

Синхронизация потоков.

  1. Объекты синхронизации могут находится в двух состояниях.

  1. signaled – свободен

  2. non-signaled – занят

  1. Если состояние свободное, то работа потока разрешена, если в занятом, то запрещена. Для созда-ния объектов синхронизации используются функции типа

CreateMutex(…) (тот кто открывает, тот и закрывает, нет счётчика),

CreateSemaphore(…) (есть счётчик),

CreateEvent(…).

Они возвращают дескриптор (указатель) на созданный объект.

  1. Для перехода объектов синхронизации в свободное состояние используются функции типа

ReleaseMutex(…),

ReleaseSemaphore(…),

ReleaseEvent(…).

  1. Для ожидания освобождения события используются функции

WaitForSingleObject(…) – ожидает освобождение какого-либо одного объекта. В качестве пара-метров передаётся дескриптор объекта, время ожидания.

WaitForMultipleObject(…) – ожидает освобождения нескольких объектов. В качестве параметров выступают указатель на массив дескрипторов, количество ожидаемых объектов, время ожидания и тип ожидания (все объекты или хотя бы один объект).

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

CreateMutex(…);

WaitForSingleObject(…);

ОС анализирует, в каком состоянии находится объект синхронизации. Если объект синхронизации находится в состоянии non-signaled, то ОС прекращает выполнение этого потока.

// Обработка базы данных.

Если объект занят, то обработка не будет происходить.

ReleaseMutex(…)

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

Критические секции.

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

Critical_Section cs1;

Обычно состоит из следующих полей: счётчика блокировок, счётчика рекурсий, идентификатора потока, который владет критической секцией в данный момент времени.

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

InitializeCriticalSection(&cs1);

Delete CriticalSection(&cs1) – удаление критической секции.

EnterCriticalSection(&cs1) – вход в критическую секцию.

// обработка данных

LeaveCriticalSection(&cs1) – выход из критической секции.

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

Лекция № 12.