2009-03-07 10 views
6

Este:¿Puede un múltiplo de disparo único SetEvent() WaitForSingleObject()

http://msdn.microsoft.com/en-us/library/ms686915(VS.85).aspx

parecería no sugerir.

Tengo tres procesos de comunicación a través de tuberías. El Proceso A crea un evento, Proceso B & C cada uso WaitForSingleObject (en un segundo hilo).

Así que ahora tenemos -TWO- Procesos cada uno esperando un evento -SINGLE-.

El proceso A desencadena el evento con SetEvent(), el proceso B responde, el proceso C no.

Conclusión:

Cada WaitForSingleObject() requiere un evento único ... ¿Correcto?

Respuesta

5

Utilice eventos de restablecimiento manual para desencadenar varios subprocesos fuera de un solo evento.

Here es un ejemplo que utiliza "restablecimiento manual Evento" bandera

+0

Desafortunadamente no tengo control sobre el proceso A, así que no puedo implementar eso. –

2

Puede utilizar los Evenets de rearme manual y la función PulseEvent a liberar a todos los hilos que actualmente están esperando para el evento.

Sin embargo, tenga en cuenta que este enfoque es intrínsecamente picante, ya que no hay forma de saber cuáles son "los hilos que esperan ...". Debería usar un mecanismo de sincronización más confiable si se necesitan coincidencias exactas de los eventos wakeup/2 wait.

+0

No mencioné esto, pero no tengo ningún control sobre el proceso A, pero miraré la función PulseEvent para futuras referencias ... gracias. –

+0

Si puede cambiar solo hilos de B & C, sería mejor despertar un hilo del otro (es decir, A -> B -> C) en lugar de intentar despertar todos los hilos de A. Por cierto, si no lo hace controle A, debe tener algún protocolo/interfaz de bloqueo/activación, y mencione esto en la pregunta. – jpalecek

+1

No utilice PulseEvent, consulte http://blogs.msdn.com/oldnewthing/archive/2005/01/05/346888.aspx – CesarB

0

espero que este ejemplo puede ayudar a:

handle1A = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME) 

handle1B = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME) 

handle2A = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME+GetCurrentThreadId()) 

handle2B = CreateEvent(LPSECURITY_ATTRIBUTES, ManualReset, InitialState, NAME+GetCurrentThreadId()) 

A) si se crea un evento con el mismo NAME, cada setEvent señalización toda waitforsingleobjects

SetEvent(handle1A) // Send signaling to handle1A and handle1B 

B) si se crea un evento con un único NAME, el setEvent solo envía la señal a la manija referenciada

SetEvent(handle2) // Send signling only to handle2A. The Id Thread is unique 
0

Un evento puede notificar varios hilos si se trata de un evento de restablecimiento manual. Un evento de reinicio automático no puede hacer eso. Si hay más de una banda de rodadura esperando simultáneamente un evento de restablecimiento automático, y la configura en el estado señalizado, solo existe un hilo y lo restablece, y el comportamiento de los otros hilos no estará definido. Aunque, a partir de la documentación de Microsoft, podemos suponer que un único subproceso se cerrará mientras que otros definitivamente no saldrán. De todos modos, debemos tener en cuenta la siguiente cita: "No asuma una orden de primero en entrar, primero en salir (FIFO). Los eventos externos como los APC en modo kernel pueden cambiar la orden de espera "Origen - https://msdn.microsoft.com/en-us/library/windows/desktop/ms682655(v=vs.85).aspx

La función CreateEvent tiene el parámetro bManualReset. Si es TRUE, la función crea un objeto de evento de restablecimiento manual, que requiere el uso de la función ResetEvent para establecer el estado del evento en no señalizado. Si este parámetro es FALSE, la función crea un objeto de evento de restablecimiento automático y el sistema restablece automáticamente el estado del evento a no señalizado después de que se ha liberado un único hilo en espera, es decir, ha salido de una función como WaitForMultipleObjects o WaitForSigleObject, pero, como Escribí antes, solo un hilo será notificado, no todos.

Como se acerca el PulseEvent - es poco fiable y nunca se debe utilizar - ver https://msdn.microsoft.com/en-us/library/windows/desktop/ms684914(v=vs.85).aspx

Sólo esos hilos son notificados por PulseEvent que están en el estado de "espera" en el momento PulseEvent se llama. Si se encuentran en cualquier otro estado, no se les notificará, y es posible que nunca se sepa con certeza cuál es el estado del hilo. Un subproceso que espera en un objeto de sincronización se puede eliminar momentáneamente del estado de espera mediante una Llamada a procedimiento asíncrono en modo kernel, y luego volver al estado de espera después de que se completa el APC. Si la llamada a PulseEvent ocurre durante el tiempo en que el hilo se ha eliminado del estado de espera, el hilo no se lanzará porque PulseEvent libera solo los hilos que están esperando en el momento en que se llama. Puede encontrar más información sobre el modo de núcleo llamadas a procedimiento asincrónico (APC) en los siguientes enlaces:

Puede obtener más ideas sobre auto restablecer eventos y eventos de reinicio manual del siguiente artículo:

Cuestiones relacionadas