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


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


if (WAIT_TIMEOUT == dwWaitRet)
{

// срок ожидания истек, выясняем, не стало ли какое-нибудь выражение
// истинным, проверяя состояние семафора hsemOnlyOne
dwWaitRet = WaitForSingleObject(hsemOnlyOne, 0);

if (WAIT_TIMEOUT == dwWaitRet}
{
// если семафор не был переведен в свободное состояние,
// какое-то выражение дало TRUE, надо выяснить - какое
dwWaitRet = WaitForMultipleObjects(dwExpNum, ahThreads, FALSE. INFINITE);
}
else
{
// ни одно выражение не стало TRUE,
// и WaitForSingleObject просто отдала нам семафор
dwWaitRet = WAIT_TIMbOUT;
}
}

Я не даю другим выражениям стать истинными за счет ожидания на семафоре. Это приводит к уменьшению счетчика семафора до 0, и никакой OR-поток не может про будиться. Но где-то после вызова функции WaitForMultipleObjects из основного пото ка и обращения той к WaitForSingleObject одно из выражений может стать истинным Вот почемуя проверяю значение, возвращаемое WaitForSingleQbject. Если она возвра щает WAIT_OBJECT_0, значит, семафор захвачен основным потоком и ни одно из выражений не стало истинным. Но если она возвращает WAIT_TIMEOUT, какое-то выражение все же стало истинным, прежде чем основной поюк успел захватить се мафор. Чтобы выяснить, какое именно выражение дало TRUE, основной поток снова вызывает WaitForMultipleObjects, но уже с временем ожидания, равным INFINITE; здесь все в порядке, так как я знаю, что семафор захвачен OR-потоком и этот поток вот-вот завершится Теперь я должен пробудить остальные OR-потоки, чтобы корректно за вершить их Это делается в цикле, из которого вызывается QueueUserAPC (о ней я уже рассказывал).

Поскольку реализация WintForMultipleExpressions основана на использовании груп пы потоков, каждый из которых ждет на своем наборе объектов, объединяемых по AND, мьютексы в ней неприменимы. В отличие от остальных объектов ядра мьютек сы могут передаваться потоку во владение. Значит, если какой-нибудь из моих AND потоков заполучит мьютекс, то по его завершении произойдет отказ от мьютекса. Вот когда Microsoft добавит в Windows API функцию, позволяющую одному потоку пере давать права на владение мьютексом другому потоку, тогда моя функция WaitFor MultipleExpressions и сможет поддерживать мьютексы. А пока надежного и корректного способа ввести в WattForMultipleExpressions такую поддержку я не вижу.

WaitForMultExp




Начало  Назад  



Книжный магазин