Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

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




Обобщенный алгоритм доступа к критическому ресурсу с использованием объектов синхронизации

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

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

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

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

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

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

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

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

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

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

Для запуска потока выполнения необходимо использовать системный вызов 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.




Поделиться с друзьями:


Дата добавления: 2015-01-03; Просмотров: 269; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.032 сек.