Auto Reset Event
От: AMurchick  
Дата: 24.10.02 03:02
Оценка:
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.
Re: Auto Reset Event
От: Андрей Тарасевич Беларусь  
Дата: 24.10.02 03:49
Оценка:
Здравствуйте 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.


Недостаточно информации.

Кстати, если нужно дождаться просто завершения потока, то можно делать ожидание прямо на хэндле потока. Не надо заводить никаких дополнительных событий.
Best regards,
Андрей Тарасевич
Re[2]: Auto Reset Event
От: AMurchick  
Дата: 24.10.02 04:15
Оценка:
Здравствуйте Андрей Тарасевич, Вы писали:

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 проваливается только по таймауту.
Кстати, такое поведение и в релизном билде.

АТ>Кстати, если нужно дождаться просто завершения потока, то можно делать ожидание прямо на хэндле потока. Не надо заводить никаких дополнительных событий.

Спасибо за информацию, сейчас погляжу доку.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.