CreateEvent
The CreateEvent function creates or opens a named or unnamed event object.
HANDLE CreateEvent(
LPSECURITY_ATTRIBUTES lpEventAttributes, // SD
BOOL bManualReset, // reset type
BOOL bInitialState, // initial state
LPCTSTR lpName // object name
);
...
bManualReset
[in] Specifies whether a manual-reset or auto-reset event object is created.
If TRUE, then you must use the ResetEvent function to manually reset the state to nonsignaled.
If FALSE, the system automatically resets the state to nonsignaled
after a single waiting thread has been released.
Собственно вопрос — что значит
a single waiting thread has been released?
Значит ли это то, что такой event сбросится сразу после завершения функции
WaitForSingleObject с кодом возврата
WAIT_OBJECT_0 или сброс произойдет только после того, как завершится нитка, в которой был вызов
WaitForSingleObject?
Проблема в следующем — объект ждет завершения треда:
void OBJECT::OBJECT()
{
sevent = CreateEvent(NULL, FALSE, FALSE, NULL);
}
...
DWORD WINAPI OBJECT::play_thread(LPVOID dummy)
{
OBJECT * rd = (OBJECT *)dummy;
...
SetEvent(rd->sevent);
return 1;
}
void OBJECT::stop()
{
....
DWORD wres = WaitForSingleObject(sevent, 5000);
if (wres == WAIT_TIMEOUT)
...
}
Первый раз все происходит как надо, но event остается в Signaled state.
Если после
WaitForSingleObject вставить
ResetEvent(sevent) — то все работает как надо.
PulseEvent() не подходит, т.к. нитка может завершиться раньше, чем будет вызванна
WaitForSingleObject.
Здравствуйте AMurchick, Вы писали:
AM>AM>CreateEvent
AM>The CreateEvent function creates or opens a named or unnamed event object.
AM>
AM>AM>HANDLE CreateEvent(
AM> LPSECURITY_ATTRIBUTES lpEventAttributes, // SD
AM> BOOL bManualReset, // reset type
AM> BOOL bInitialState, // initial state
AM> LPCTSTR lpName // object name
AM>);
AM>
AM>AM>...
AM>bManualReset
AM>[in] Specifies whether a manual-reset or auto-reset event object is created.
AM> If TRUE, then you must use the ResetEvent function to manually reset the state to nonsignaled.
AM> If FALSE, the system automatically resets the state to nonsignaled
AM> after a single waiting thread has been released.
AM>
AM>Собственно вопрос — что значит a single waiting thread has been released?
AM>Значит ли это то, что такой event сбросится сразу после завершения функции WaitForSingleObject с кодом возврата WAIT_OBJECT_0 или сброс произойдет только после того, как завершится нитка, в которой был вызов WaitForSingleObject?
Событие сбросится еще до завершения функции 'WaitForSingleObject'. Вся идея состоит в том, что в ситуации, когда сразу
несколько потоков ожидают события с автоматическим сбросом и это событие устанавливается, то только
один из этих ожидающих потоков дождется этого события (неизвестно, какой) и продолжит работу, а остальные потоки и не заметят того, что событие устанавливалось, и продолжат ожидание. Если же событие имеет ручной сброс, то
все ожидающие потоки дождутся события и продолжат работу.
AM>Проблема в следующем — объект ждет завершения треда:
AM>AM>void OBJECT::OBJECT()
AM>{
AM> sevent = CreateEvent(NULL, FALSE, FALSE, NULL);
AM>}
AM>...
AM>DWORD WINAPI OBJECT::play_thread(LPVOID dummy)
AM>{
AM>OBJECT * rd = (OBJECT *)dummy;
AM>...
AM> SetEvent(rd->sevent);
AM> return 1;
AM>}
AM>void OBJECT::stop()
AM>{
AM>....
AM>DWORD wres = WaitForSingleObject(sevent, 5000);
AM> if (wres == WAIT_TIMEOUT)
AM>...
AM>}
AM>
AM>Первый раз все происходит как надо, но event остается в Signaled state.
AM>Если после WaitForSingleObject вставить ResetEvent(sevent) — то все работает как надо.
AM>PulseEvent() не подходит, т.к. нитка может завершиться раньше, чем будет вызванна WaitForSingleObject.
Недостаточно информации.
Кстати, если нужно дождаться просто завершения потока, то можно делать ожидание прямо на хэндле потока. Не надо заводить никаких дополнительных событий.
Здравствуйте Андрей Тарасевич, Вы писали:
AM>>AM>>bManualReset
AM>>[in] Specifies whether a manual-reset or auto-reset event object is created.
AM>> If TRUE, then you must use the ResetEvent function to manually reset the state to nonsignaled.
AM>> If FALSE, the system automatically resets the state to nonsignaled
AM>> after a single waiting thread has been released.
AM>>
AM>>Собственно вопрос — что значит a single waiting thread has been released?
AM>>Значит ли это то, что такой event сбросится сразу после завершения функции WaitForSingleObject с кодом возврата WAIT_OBJECT_0 или сброс произойдет только после того, как завершится нитка, в которой был вызов WaitForSingleObject?
АТ>Событие сбросится еще до завершения функции 'WaitForSingleObject'. Вся идея состоит в том, что в ситуации, когда сразу несколько потоков ожидают события с автоматическим сбросом и это событие устанавливается, то только один из этих ожидающих потоков дождется этого события (неизвестно, какой) и продолжит работу, а остальные потоки и не заметят того, что событие устанавливалось, и продолжат ожидание. Если же событие имеет ручной сброс, то все ожидающие потоки дождутся события и продолжат работу.
Да, в доке написано имеено так...
АТ>Недостаточно информации.
Что нужно дополнить, ибо интересно разобраться, почему у меня wait на второй и следующий разы вываливается раньше, чем завершится нитка (какбуд-то ивент не сбрасывается) — ставил точки останова. Ежели закомментировать мой SetEvent(), то wait проваливается только по таймауту.
Кстати, такое поведение и в релизном билде.
АТ>Кстати, если нужно дождаться просто завершения потока, то можно делать ожидание прямо на хэндле потока. Не надо заводить никаких дополнительных событий.
Спасибо за информацию, сейчас погляжу доку.