Win32 використовують функцію WaitForSingleQbject (), синтаксис якої наступний:
DWORD WaitForSingleObject (HANDLE handle, DWORD timeout);
Параметри:
handle - визначає дескриптор синхронізованого об'єкта;
timeout - задає максимальний час очікування в мілісекундах (значення INFINITE свідчить про нескінченному очікуванні). p>, що повертається: Функція WaitForSingleObject () повертає такі значення: WAIT_OBJECT_0 - відбулася сигналізація об'єкта; WAIT_TIMEOUT - минув час очікування (якщо timeout не належав INFINITE), а об'єкт свого стану так і не змінив.
Можна очікувати сигналізації не одного об'єкта, а кількох відразу (деякий аналог використання декількох умов очікування для умовної змінної). Для цього використовують функцію WaitForMultipleObjects ():
DWORD WaitForMultipleObjects (DWORD count, CONST HANDLE handles, BOOL waitall, DWORD timeout);
Параметри:
count - довжина масиву дескрипторів;
handles - задає максимальний час очікування в мілісекундах (значення INFINITE свідчить про нескінченному очікуванні). p> waitall - Прапорець режиму очікування;
timeout - Аналогічна до WaitForSingleObject
що повертається значення:
Функція приймає масив дескрипторів handles довжиною count (максимальна довжина масиву 64 елемента). Режим очікування і повернене значення залежати від прапорця waitall.
- Якщо waitall дорівнює TRUE, заданий режим очікування всіх об'єктів. Очікування завершується у разі здійснення сигналізації всіх об'єктів, функція поверне WAIT_OBJECT_0.
- Якщо waitall дорівнює FALSE, заданий режим очікування одного об'єкту. Очікування завершується в разі здійснення сигналізації хоча б одного з об'єктів, функція поверне WAIT_OBJECT_0 + i, де i-індекс дескриптора цього об'єкта в масиві handles.
Стосовно до семафора, якщо він знаходиться в несигнальному стані, завдання, що викликала для нього функцію WaitForSingleObject (), знаходиться в стані очікування. Коли ж стан семафора стає сигнальним, робота завдання поновлюється. p> З кожним семафором зв'язується лічильник, початкове і максимальні значення якого задаються при створенні семафора. Значення цього лічильника зменшується, коли завдання викликає для семафора функцію WaitForSingleObject () або WaitForMultipleObject (), і збільшується при виклику функції ReleaseSemaphore (). p> Якщо значення лічильника семафора дорівнює нулю, він знаходиться в несигнальному стані. Якщо ж це значення більше нуля, семафор переходить в сигнальний стан.
Наприклад. Нехай додаток створило семафор, вказавши для нього максимальне значення лічильника, рівну трьом. Нехай початкове значення цього лічильника також буде дорівнює трьом. p> Якщо в цій ситуації кілька запускаються по черзі завдань будуть виконувати за допомогою функції WaitForSingleObject () очікування семафора, то перші три запущені завдання будуть працювати, а всі інші перейдуть в стан очікування. p> Це пов'язано з тим, що перші три виклику функції WaitForSingleObject () приведуть до послідовного зменшення значення лічильника семафора до нуля, внаслідок чого семафор переключиться у несигнальному стан.
Завдання, запущена четвертої, викличе функцію WaitForSingleObject () для невідзначеними семафора, внаслідок чого вона буде чекати. Точно також, завдання, запущені після запуску четвертого завдання, будуть виконувати очікування для того ж семафора.
Як довго триватиме очікування?
До тих пір, поки одна з перших трьох завдань не звільнить семафор, збільшивши його лічильник на одиницю викликом функції ReleaseSemaphore (). Відразу після цього буде запущена одне із завдань, які очікують наш семафор. p> Розглянемо функції програмного інтерфейсу операційної системи Windows, призначені для роботи з семафора.
Для того, щоб створити семафор, додаток повинен викликати функцію CreateSemaphore (), синтаксис якої виглядає наступним чином.
HANDLE CreateSemaphore (LPSECURITY_ATTRIBUTES lpThreadSecurity, LONG lSemInitialCount, LONG lSemMaxCount, LPCTSTR lpszSemName)
Параметри:
lpThreadSecurity - покажчик на структуру, що містить атрибути доступу до семафора. Якщо атрибути не використовуються, він може містити значення, рівне NULL;
lSemInitialCount - початкове значення лічильника в семафорі, яке має бути більше або дорівнює нулю і менше або дорівнює значенню параметра lSemMaxCount;
lSemMaxCount - максимальне значення лічильника в семафорі. Це значення має бути більше нуля;
lpszSemName-вказівник на рядок, містить ім'я семафора. Ім'я не повинно збігатися з ім'ям існуючого події, семафора або об'єкта відображення файлу;
повертається. При успішному виконанні функція повертає хендл створеного семафора, в іншому випадку - повертається NULL.
Для знищення семафора ви повинні передати його ідентифікатор функції CloseHandle (). Зауважим...