Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


Программа-пример WaitForMultExp - часть 2


Поток, который вызвал WaitForMultipleExpressions (и который породил все OR-пo токи), должен ждать, пока одно из OR-выражений пе станет истинным. Для этого он вызывает функцию WaitForMultipleQbjeclsEx. В параметре dwObjects передается коли чество порожденных потоков (OR-выражений), а параметр phObjects указывает на массив описателей этих потоков. В паряметр fWaitAll записывается FALSE, чтобы ос новной поток пробудился сразу после того, как оанет истинным любое из выраже ний. И, наконец, в параметре dwMilliseconds передается значение, идентичное тому, которое было указано в аналогичном параметре при вызове WaitForMultipleExpressions

Если в течение заданного времени ни одно из выражений не становится истин ным, WaitForMultipleObjectsEx возвращает WAIT_TIMHOUT, и это же значение возвpa щается функцией WaitForMiltipleExpressions А если какое-нибудь выражение становит

ся истинным, WaitForMultipleObjectsEx возвращает индекс, указывающий, какой поток завершился Так как каждый поток представляет отдельное выражение, этот индекс сообщает и то, какое выражение стало истинным; этот же индекс возвращается и функцией WaitForMultipleExpressions.

На этом мы, пожалуй, закончим рассмотрение того, как работает функция WaiWor MultipleExpressions. Но нужно обсудить еще три вещи. Во-первых, нельзя допустить, чтобы несколько OR-потоков одновременно пробудились в своих вызовах WaitFor MultipleObjectsEx, так как успешное ожидание некоторых объектов ядра приводит к изменению их состояния (например, у семафора счетчик уменьшается на 1) WaitFor MultipleExpressions ждет лишь до тех пор, пока одно из выражений не станет истин ным, а значит, я должен предотвратить более чем однократное изменение состояния объекта

Решить эту проблему на самом деле довольно легко. Прежде чем порождать OR потоки, я создаю собственный объект-семафор с начальным значением счетчика, равным 1 Далее каждый OR-поток вызывает WaitForMultipleObjectsEx и передает ей не только описатели объектов, связанных с выражением, но и описатель этого семафо ра. Теперь Вы понимаете, почему в каждом наборе не может быть более 63 описате лей? Чтобы OR-поток пробудился, должны освободиться все объекты, которые он ждет, — в том числе мой специальный семафор. Поскольку начальное значение его счетчика равно 1, более одного OR-потока никогда не пробудится, и, следовательно, случайного изменения состояния каких-либо других объектов нс произойдет.




Начало  Назад  Вперед