Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
спиос-методичка-часть2.doc
Скачиваний:
15
Добавлен:
13.04.2015
Размер:
266.75 Кб
Скачать
    1. Обобщенный алгоритм доступа к критическому ресурсу с использованием объектов синхронизации

При использовании мъютексов или семафоров обобщенный алгоритм доступа к критическому ресурсу состоит из четырех шагов:

  1. Занять объект(ы) синхронизации (мъютекс, семафор).

  2. Ожидать освобождения объекта(ов) синхронизации.

  3. Выполнить критическую секцию.

  4. Освободить объект(ы) синхронизации.

Перед первым открытием мъютексов или семафоров они должны быть созданы.

При использовании объектов «критическая секция» обобщенный алгоритм доступа к критическому ресурсу состоит из трех шагов:

  1. Открыть критическую секцию.

  2. Выполнить критическую секцию.

  3. Закрыть критическую секцию.

    1. Практические аспекты

Для запуска потока выполнения необходимо использовать системный вызов CreateThread.

HANDLE CreateThread(

LPSECURITY_ATTRIBUTES lpThreadAttributes, //дескриптор защиты(DWORD)

SIZE_T dwStackSize, //начальный размер стека (DWORD)

LPTHREAD_START_ROUTINE lpStartAddress, //функцияпотока(DWORD)

LPVOID lpParameter, //параметрпотока(DWORD)

DWORD dwCreationFlags, //опциисоздания(DWORD)

LPDWORD lpThreadId //идентификаторпотока(DWORD)

);

Параметры:

lpThreadAttributes [in]Адрес структуры типаSECURITY_ATTRIBUTES, которая обуславливает, может ли возвращенный дескриптор быть унаследован дочерними процессами. ЕслиlpThreadAttributesявляется значением ПУСТО (NULL), дескриптор не может быть унаследован.

dwStackSize [in]Начальный размер стека, в байтах. Система округляет это значение до самой близкой страницы памяти. Если это значение нулевое, новый поток использует по умолчанию размер стека исполняемой программы.

lpStartAddress [in] Адрес определяемой программой функции (подпрограммы), код которой исполняется потоком и обозначает начальный адрес потока. Описание функцииThreadProc см. ниже.

lpParameter [in] Адрес переменной, которая передается в поток.

wCreationFlags [in] Флажки, которые управляют созданием потока. Если установлен флажокCREATE_SUSPENDED, создается поток в состоянии ожидания и не запускается до тех пор, пока не будет вызвана функцияResumeThread. Если это значение нулевое, поток запускается немедленно после создания.

lpThreadId [out] Указатель на переменную, которая принимает идентификатор потока.

Функция ThreadProc- определяемая программой функция, которая служит как начальный адрес для потока.ThreadProc– является обобщенным названием подпрограмм обработчиков потока, т.е.ThreadProcявляется символом – заместителем для определяемого программой имени функции. Каждому потоку может быть сопоставлена своя функция обработчик ThreadProc, т.е. функция, выполняющая действия потока. Тем не менее, одна и та жеThreadProcможет быть сопоставлена нескольким потокам. В любом случаеThreadProcдолжна обладать свойством реентерабельности. АдресThreadProcопределяется при вызове функцииCreateThreadилиCreateRemoteThread. ОписаниеThreadProcдолжно подчиняться следующему синтаксису:

DWORD WINAPI ThreadProc(

LPVOID lpParameter //данныепотока(DWORD)

);

Параметры:

lpParameter [in]Адрес на данные потока пересылаемые в функцию. Этот адрес указывается как параметрlpParameterфункцииCreateThreadилиCreateRemoteThread.

Создание Мъютекса осуществляется системным вызовом CreateMutex.

Синтаксис:

HANDLE CreateMutex(

LPSECURITY_ATTRIBUTES lpSecurityAttribs,

BOOL bInitialOwner,

LPCTSTR lpszMutexName

);

LPSECURITY_ATTRIBUTES lpSecurityAttribs [in, optional] Адрес структуры типа SECURITY_ATTRIBUTES, которая обуславливает, может ли возвращенный дескриптор быть унаследован дочерними процессами. ЕслиlpSecurityAttribsявляется значением ПУСТО (NULL), дескриптор не может быть унаследован.

BOOL bInitialOwner [in]Если параметр установлен вTRUE, то мъютекс создается захваченным потоком создавшим его, еслиFALSEто мъютекс создается свободным.

lpName [in, optional]Адрес строки с нулевым завершителем, содержащей имя мъютекса. Строка чувствительна к регистру символов.

После создания, мъютекс может быть захвачен системным вызовом OpenMutex.

Синтаксис:

HANDLE WINAPI OpenMutex(

DWORD dwDesiredAccess,

BOOL bInheritHandle,

LPCTSTR lpName

);

Параметры:

dwDesiredAccess [in]Определяет режим доступа к мъютексу. Для доступа достаточно праваSYNCHRONIZE, для изменения прав защиты необходимо указатьMUTEX_ALL_ACCESS.

bInheritHandle [in]Если параметр установлен вTRUE, то дочерние процессы могут наследовать мъютекс, в противном случае нет.

lpName [in]Адрес строки с нулевым завершителем, содержащей имя мъютекса. Строка чувствительна к регистру символов.

Мъютекс может использоваться несколькими процессами. Один из взаимодействующих процессов создаёт его, и все процессы могут работать с ним. Поэтому для открытия мъютекса используется не дескриптор, а его имя. Для дальнейшей работы с мъютексом OpenMutex как и CreateMutex возвращает его дескриптор.

Освобождение мъютекса осуществляется системным вызовом ReleaseMutex.

Синтаксис:

BOOL WINAPI ReleaseMutex(

HANDLE hMutex

);

Параметры:

hMutex [in] Дескриптор объекта мъютекс который возвращен функциями CreateMutex или OpenMutex.

Создание семафора осуществляется системным вызовом CreateSemaphore.

Синтаксис:

HANDLE WINAPI CreateSemaphore(

LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,

LONG lInitialCount,

LONG lMaximumCount,

LPCTSTR lpName

);

Параетры:

lpSemaphoreAttributes [in, optional] Адрес структуры типа SECURITY_ATTRIBUTES, которая обуславливает, может ли возвращенный дескриптор быть унаследован дочерними процессами. ЕслиlpSecurityAttribsявляется значением ПУСТО (NULL), дескриптор не может быть унаследован.

lInitialCount [in]Начальное состояние семафора. Должно быть больше или равно 0 и меньше или равноlMaximumCount. Состояние семафора сигнальное если счетчик больше 0 и несигнальное если счетчик равен 0. Счетчик уменьшается, когда функция ожидания впускает ожидавший поток в критическую секцию и увеличивается, когда поток вызывает функциюReleaseSemaphore.

lMaximumCount [in]Максимальное значение счетчика семафора. Показывает сколько потоков может одновременно захватить семафор.

lpName [in, optional]Адрес строки с нулевым завершителем, содержащей имя семафора. Строка чувствительна к регистру символов.

После создания семафора он может быть захвачен системным вызовом OpenSemaphore.

Синтаксис:

HANDLE WINAPI OpenSemaphore(

DWORD dwDesiredAccess,

BOOL bInheritHandle,

LPCTSTR lpName

);

Параметры:

dwDesiredAccess [in]Определяет режим доступа к семафору. Для доступа достаточно праваSYNCHRONIZE, для изменения прав защиты необходимо указатьSEMAPHORE_ALL_ACCESS.

bInheritHandle [in]Если параметр установлен вTRUE, то дочерние процессы могут наследовать семафор, в противном случае нет.

lpName [in]Адрес строки с нулевым завершителем, содержащей имя семафора. Строка чувствительна к регистру символов.

Семафор может использоваться несколькими процессами. Один из взаимодействующих процессов создаёт его, и все процессы могут работать с ним. Поэтому для открытия семафора используется не дескриптор, а его имя. Для дальнейшей работы с семафором OpenSemaphore как и CreateSemaphore возвращает его дескриптор.

Освобождение семафора осуществляется системным вызовом ReleaseSemaphore.

BOOL WINAPI ReleaseSemaphore(

HANDLE hSemaphore,

LONG lReleaseCount,

LPLONG lpPreviousCount

);

Параметры:

hSemaphore [in] Дескриптор объекта семафор который возвращен функциями CreateSemaphore или OpenSemaphore.

lReleaseCount [in]Значение на которое счетчик семафора должен быть увеличен.

lpPreviousCount [out, optional]Адрес переменной в которую будет записано предыдущее значение счетчика семафора. Устанавливается вNULLесли оно не требуется.

Ожидание освобождения объекта синхронизации может осуществляться системными вызовами WaitForSngleObject или WaitForMultipleObjects.

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

Синтаксис:

DWORD WaitForMultipleObjects(DWORD dwObjectCount,

CONST HANDLE* lphObjectList,

BOOL bWaitAll,

DWORD dwTimeoutInterval)

Параметры:

dwObjectCount DWORD Количество дескрипторов объектов в массиве lphObjectList. Максимально допустимое число дескрипторов объектов равноMAXIMUM_WAIT_OBJECTS.

lphObjectList CONST HANDLE*Указатель на массив дескрипторов объектов. У всех дескрипторов должны быть права доступа типаSYNCHRONIZE.

bWaitAll BOOLЕсли установлено значениеFALSE, выполняется ожидание перехода в сигнальное состояние любого объекта, а еслиTRUE– то всех объектов.

dwTimeoutInterval DWORDЕсли установлено значение0, проверяется состояние всех объектов и сразу же осуществляется возврат из функции. Если же установлено значениеINFINITE, время ожидания не используется. Иначе параметр определяет число миллисекунд времени ожидания.

Возвращаемое значение DWORD. Если выполнение функции оказывается успешным, возвращаемое значение определяет объект, который обусловил возврат из данной функции ожидания. В противном случае возвращаетсяWAIT_FAILED. Для возврата кода ошибки используется функцияGetLastError.

Объект «критическая секция» не может использоваться для синхронизации процессов. Он может использоваться только для синхронизации потоков одного процесса. Для его применения необходимо заранее объявить переменную (структуру) типа CRITICAL_SECTION. В дальнейшем передавать её адрес в системные функции. Для инициализации этой переменной используется функция InitializeCriticalSection. Инициализация выполняется один раз.

Синтаксис:

void WINAPI InitializeCriticalSection(

LPCRITICAL_SECTION lpCriticalSection

);

Параметры:

lpCriticalSection [out] Адрес структуры типа CRITICAL_SECTION.

После того как переменная инициализирована она используется в системных вызовах EnterCriticalSection и LeaveCriticalSection.

EnterCriticalSection– захватывает объект «критическая секция». Если он уже захвачен другим потоком, то этот поток который пытается захватить объект переводится в состояние ожидания до освобождения объекта.

Синтаксис:

void WINAPI EnterCriticalSection(

LPCRITICAL_SECTION lpCriticalSection

);

Параметры:

lpCriticalSection [in, out] Адрес структуры типа CRITICAL_SECTION, которая предварительно инициализирована функцией InitializeCriticalSection.

После выполнения доступа к критическому ресурсу поток должен освободить объект «критическая секция» функцией LeaveCriticalSection.

Синтаксис:

void WINAPI LeaveCriticalSection(

LPCRITICAL_SECTION lpCriticalSection

);

Параметры:

lpCriticalSection [in, out] Адрес структуры типа CRITICAL_SECTION, которая предварительно инициализирована функцией InitializeCriticalSection.

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

Синтаксис:

void WINAPI DeleteCriticalSection(

__inout LPCRITICAL_SECTION lpCriticalSection

);

Параметры:

lpCriticalSection [in, out] Адрес структуры типа CRITICAL_SECTION, которая предварительно инициализирована функцией InitializeCriticalSection.