Некогорое время назад я разрабатывал одно приложение и столкнулся с весьма не простым случаем синхронизации потоков Функции WaitForMultipleObjects., заставля ющей поток ждать освобождения одного или всех объектов, оказалось недостаточно Мне понадобилась функция, которая позволяла бы задавать более сложные критерии ожидания У меня было три объекта ядра процесс, семафор и событие Мой поток должен был ждать до тех пор, пока не освободтся либо процесс и семафор, либо процесс и событие
Слегка поразмыслив и творчески использовав имеющиеся функции Windows, я создал именно то, что мне требовалось, — функцию WaitWorMulttpleExpressions Ее прототип выглядит так
DWORD WINAPI WaitForMultipleExpressions( DWORD nExpObjectS, CONST HANDLE* phExpObiects, DWORD dwMilliseconds);
Перед ее вызовом Вы должны создать массив описателей (HANDLE) и инициали зировать всс cro элементы. Параметр nExpObjects сообщает число элементов в масси ве, на который указывает параметр phExpObjects. Этот массив содержит несколько наборов описателей объектов ядра; при этом каждый набор отделяется элементом, равным NULL. Функция WaitForMultipleExpressions считает все объекты в одном набо ре объединяемыми логической операцией AND, а сами наборы — объединяемыми логической операцией OR. Поэтому WaitForMultipleExpressions приостанавливает вызы вающий поток до тех пор, пока нс освободятся сразу все объекты в одном из наборов.
Вот пример. Допустим, мы работаем с четырьмя объектами ядра (см. таблицу ниже).
Обьект ядра |
Значение описателя |
Поток |
0x1111 |
Семафор |
0x2222 |
Событие |
0x3333 |
Процесс |
0x4444 |
Инициализировав массив описателей, как показано в следующей таблице, мы со общаем функции WaitForMultipleExpressions приостановить вызывающий поток до тех пор, пока не освободятся поток AND семафор OR семафор AND событие AND про цесс OR поток AND процесс,
Индекс |
Значение описателя |
Набор |
0 |
0x1111 (поток) |
0 |
1 |
0x2222 (семафор) |
|
2 |
0x0000 (OR) |
|
3 |
0x2222 (семафор) |
1 |
4 |
0x3333 (событие) |
|
5 |
0x4444 (процесс) |
|
6 |
0x0000 (OR) |
|
7 |
0x1 1 1 1 (поток) |
2 |
8 |
0x4444 (процесс) |