Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Метод рекомендации АЯ 2 семестр2.docx
Скачиваний:
112
Добавлен:
23.03.2016
Размер:
1.14 Mб
Скачать

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

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

Объекты синхронизации и их назначение представлены в таблице 2.

Примеры использования объектов синхронизации:

1. Взаимное исключение.

HANDLE HMutex; // Объявляется глобально, и все потоки имеют доступ

HMutex=CreateMutex( // Создание взаимного исключения

NULL, // атрибуты прав доступа по умолчанию

FALSE, // Взаимное исключение изначально свободно

NULL); // не присваивается имя взаимному исключению

Работа с синхронизированным объектом:

WaitForSingleObject(HMutex, // Занять взаимное исключение

Таблица 2 – Объекты синхронизации и их назначение

Синхронизирующий объект

Назначение

Используемые функции Win32 API

Взаимное исключение

Запрет доступа более чем одному потоку к общим ресурсам

CreateMutex

WaitForSingleObject

WaitForMultipleObjects

ReleaseMutex

CloseHandle

Критическая секция

Запрет доступа более чем одному потоку к одному фрагменту кода

InitializeCriticalSection

EnterCriticalSection

LeaveCriticalSection

DeleteCriticalSection

Семафор

Ограничение числа потоков, имеющих одновременный доступ к общим ресурсам

CreateSemaphore

WaitForSingleObject

WaitForMultipleObjects

ReleaseSemaphore

CloseHandle

Событие

Позволяет потоку передавать сигналы другим потокам

CreateEvent

SetEvent

PulseEvent

ResetEvent

WaitForSingleObject

WaitForMultipleObjects

CloseHandle

INFINITE); // ждите сколько нужно

Count++; // Работа с синхронизированным объектом

ReleaseMutex(HMutex); // Освободить взаимное исключение

Удалить взаимное исключение:

CloseHandle(HMutex);

Рассмотрим функции WaitForSingleObject и WaitForMultipleObjects. WaitForSingleObject имеет заголовок:

DWORD WaitForSingleObject( HANDLE hObject, DWORD dwMilliseconds);

Когда поток вызывает эту функцию, первый параметр hObject идентифицирует объект ядра (объекты «Взаимное исключение», «Семафор» и «Событие» являются объектами ядра Windows [4]), поддерживающий состояния «свободен- занят». Второй параметр dwMilliseconds указывает, сколько времени (в миллисекундах) поток готов ждать освобождения объекта, значение INFINITE означает ждать без ограничения времени. При выходе из функции она возвращает значение, которое можно использовать:

WAIT_OBJECT_0 – объект свободен;

WAIT_TIMEOUT – заданное время ожидания (таймаут) истекло;

WAIT_ FAILED – неверное значение параметра.

Функция WaitForMultipleObjects аналогична WaitForSingleObject, но она позволяет ждать освобождения сразу нескольких объектов или какого-то одного из них. Заголовок функции:

DWORD WaitForMultipleObjects( DWOHD dwCount, CONST HANDLE* phObjects, BOOL fWaitAll, DWORD dwMilliseconds);

Параметр dwCount определяет число ожидаемых объектов ядра, его значение в пределах от 1 до MAXIMUM_WAIT_OBJECTS (в заголовочных файлах Windows оно определено как 64). Параметр phObject – указатель на массив объектов ядра.

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

Параметр dwMilliseconds идентичен одноименному параметру функции WaitForSingleObject.

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

InitializeCriticalSection – данная функция создает объект под названием критическая секция. Параметры функции:

указатель на структуру CRITICAL_SECTION.

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

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

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

DeleteCriticalSection – удалить объект "критическая секция". Параметр аналогичен предыдущим.