Потоки. Синхронизирующие объекты Windows, страница 3

LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, //указатель на структуру типа SECURITY_ATTRIBUTES или 0

                        LONG lInitialCount, // позволяет задать - сколько из этих ресурсов доступно изначально (на момент создания). Это значение должно лежать в диапазоне 0- lMaximumCount. Семафор свободен, если его счетчик больше нуля и занят, если счетчик равен 0.

LONG lMaximumCount, // максимальное значение счетчика (должно быть больше нуля)

LPCTSTR lpName); //Если этот параметр совпадает с именем уже существующего самафора, параметры lInitialCount и lMaximumCount игнорируются. Если lpName равен 0, семафор создается без имени, и им можно пользоваться только в пределах одного процесса.

Получить доступ к уже существующему объекту:

HANDLE OpenSemaphore( DWORD fdwAccess, BOOL bInhentHandle, PCTSTR pszName);

Когда семафор в данном потоке больше не нужен, не забудьте вызвать функцию:

BOOLCloseHandle(HANDLE hObject);     //где hObject – описатель семафора, возвращенный функцией CreateSemaphore()

Поток увеличивает значение счетчика текущего числа ресурсов, вызывая функцию ReleaseSemaphore

BOOL ReleaseSemaphore( HANDLEhSem, LONG lReleaseCount, PLONG pPreviousCount);

Она просто складывает величину lReleaseCount со значением счетчика текущего числа ресурсов. Обычно в параметре lReleaseCount передают 1, но это вовсе не обязательно. Функция возвращает исходное значение счетчика ресурсов в *plPreviousCount Если Вас не интересует это значение (а в большинстве программ так оно и есть), передайте в параметре plPrviousCount значение 0.

9.1. Именованный семафор

Синхронизация потоков разных процессов посредством именованного семафора.

10. Синхронизация потоков посредством объекта – event

Событие  - самая примитивная разновидность синхронизирующих объектов – они просто уведомляют об окончании какой-либо операции.

События с автоматическим сбросом переводятся функциями WaitForSingleObject() или WaitForMultipleObjects() в занятое состояние. Таким образом, если в какой-то момент времени событие с автоматическим сбросом оказывается свободным, то только один из потоков, ожидающих данный объект-событие, пробуждается (а событие переводится системой опять в занятое состояние) => остальные продолжают спать. Если ожидающих потоков нет, объект-событие остается в свободном состоянии.

События с ручным сбросом автоматически не переустанавливаются в занятое состояние функциями WaitForSingleObject() и WaitForMultipleObjects().У Вас может быть несколько потоков, ждущих возникновения одного события. Когда событие наконец происходит, система пробуждает все ожидающие данное событие потоки.

Создание объекта-событие. Объекты-события создаются функцией:

HANDLE CreateEvent(//если объект создать не удалось - 0

LPSECURITY_ATTRIBUTES lpEventAttributes, //указатель на структуру SECURITY_ATTRIBUTES или 0

                   BOOL bManualReset, //TRUE – создастся событие со сбросом вручную, FALSE – с автосбросом.

BOOL bInitialState, // начальное состояние объекта-события: TRUE – свободен (событие произошло – потоки, желающие получить доступ к ресурсу посредством WaitForSingleObject() или WatForMultipleObjects() выполняются), FALSE – занят (событие не произошло – все потоки, желающие получить доступ к ресурсу, засыпают).

LPCTSTR lpName ); //Если объект-событие с данным именем уже существует, то возвращаемый описатель характеризует существующий объект-событие, а поля bManualReset и bInitialState игнорируются, так как они уже были установлены при создании объекта.

Замечание: если Вы хотите получить описатель существующего объекта-события – пользуйтесь функцией

HANDLE OpenEvent( DWORD dwDesiredAccess, BOOL bInheritHandle, LPCTSTR lpName );

Когда объект-событие в данном потоке больше не нужен, не забудьте вызвать функцию:

CloseHandle(HANDLE hObject); //где hObject – описатель события, возвращенный функцией CreateEvent()

10.1. Событие с ручным сбросом

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

События этого типа не переводятся в занятое состояние функциями ожидания (WaitForSingleObject…)!!!.

Событие с ручным сбросом переводится в свободное состояние функцией:

BOOL SetEvent(HANDLE hEvent );   //все ожидающие потоки выполняются

После перевода объекта в свободное состояние он пребывает в нем, пока какой-нибудь поток явно не сбросит событие в занятое состояние вызовом:

BOOL ResetEvent(HANDLE hEvent );

Замечание: иногда после вызова SetEvent() (событие освобождается) тут же его нужно опять «занять», то есть вызвать ResetEvent(). Для такой ситуации предусмотрена специальная функция:

BOOL PulseEvent(HANDLE hEvent );//после возврата управления функцией //событие остается в занятом состоянии


Для GUI-приложения:

MsgWaitForMultipleObjects!!! – без сообщений!!!

10.1.1. Именованное событие

Синхронизация потоков посредством именованного объекта-события.

10.2. Событие с автоматическим сбросом

Позволяет уведомить об окончании операции один поток. Функции ожидания переводят объект в занятое состояние.