2009-08-14 2 views
1

Я создаю 3 события с помощью следующей функции:win32: Получить состояние объекта события

HANDLE WINAPI CreateEvent(...); 

Я жду все (bWaitAll устанавливается в TRUE) объектов событий или тайм-аут с:

DWORD WINAPI WaitForMultipleObjects(...); 

возвращаемое значение:

WAIT_TIMEOUT 

Есть ли простой способ проверить каждое событие, чтобы найти тот, который был (где) не установлен?

В качестве примера:

HANDLE evt1 = .... 
HANDLE evt2 = .... 
HANDLE evt3 = .... 

HANDLE evts[3] = .... 

DWORD ret = ::WaitForMultipleObjects(3, evts, TRUE, 10000); 

После 10 сек:

  • 'RET' является WAIT_TIMEOUT.
  • evt1 установлен
  • evt2 НЕ установлен
  • evt3 установлен

Возвращаемое значение говорит мне: «Интервал времени ожидания истекло, и условия, указанные в параметре bWaitAll не удовлетворены.» , но не тот, который был указан, а какой нет.

Спасибо,

ответ

3

Да, после того, как WaitForMultipleObjects() возвращала называют WaitForSingleObject() для каждого события с указанием нулевой тайм-аут.

Он вернет WAIT_TIMEOUT для событий, которые не сигнализируются, и WAIT_OBJECT_0 для сигнальных событий. Не забудьте проверить WAIT_FAILED.

Несомненно, каждое состояние события могло быть изменено по сравнению с состояниями, которые у них были в момент возвращения WaitFormultipleObjects().

+2

Этот вид побеждает цель WaitForMultipleObjects! – 2009-08-14 13:53:50

+1

Поскольку это принято, я должен повторить здесь свое предупреждение о том, что это фактически * изменит состояние * некоторых объектов Sync. Например, если ваш «чек» преуспеет для Mutex, вы также будете владеть мьютексом. –

+0

anon - Не совсем. Вы можете подождать несколько объектов, а затем использовать ожидание для того, чтобы один объект работал, какой из них установлен. –

-1

Если вызов возвращает WAIT_TIMEOUT это означает, что ни один из объектов, которые вы ждали не сигнализировал ..

+0

Это было бы так, если бы он ожидал. Устанавливается в false, но он, кажется, подождал, что он установлен в true (он говорит, что ждет всех событий). – sharptooth

+0

Ну, если он ждет их ВСЕ, чтобы их сигнализировали, и он возвращает WAIT_TIMEOUT, они не все сигнализируются, и он должен ждать снова, пока они не станут. Либо это, либо, как вы говорите, используйте waitAll, установите false. – 2009-08-14 14:01:29

+0

+1, моя ошибка: я не был достаточно ясен. Я хочу знать, какое событие произошло после возврата WAIT_TIMEOUT. – Nicolas

2

OK. Общее переписывание после того, как вопрос был объяснен мне лучше в комментариях.

Итак, если я понимаю это прямо сейчас, вы вызываете WaitForMultipleObjects с bWaitAll, установленным в true, и когда вы возвращаете WAIT_TIMEOUT из него, хотите выяснить, какие объекты поддерживают работу.

В этом случае я с sharptooth, вроде. Вы можете вызвать WaitForSingleObject с 0 таймаутом для каждого объекта. Проблема с этим заключается в том, что у него есть побочные эффекты для некоторых объектов. Например, если вы делаете это на мьютексе, и он преуспевает, вы не только знаете, что он не был виновником, но теперь вы владеете мьютексом. Если это не то, что вы хотите, вам нужно будет сразу же его освободить.

Любое заявление, которое вы принимаете, будет подлежать условиям гонки. Поскольку вы находитесь за пределами «атомарного» вызова ожидания, вы можете пройти процесс и обнаружить, что теперь все они готовы. Вы можете вернуть набор готовых/не готовых, что не было на самом деле в вызове ожидания.

Ick.

+0

Он сообщает мне, какой объект получил сигнал, если я использую функцию с «bWaitAll» в FALSE, но я использую ее с «bWaitAll» в TRUE. – Nicolas

0

Без этой работы, так как WaitForSingleObject() вызовет автоматический сброс события, даже если время ожидания равно 0.

(Вопреки тому, что говорит MSDN).

Смежные вопросы