2009-03-20 9 views
5

Dado: llené una serie de identificadores con eventos de restablecimiento automático y los pasaré a WaitForMultipleObjects con bWaitAll = FALSE.Comportamiento de WaitForMultipleObjects cuando múltiples identificadores señalan al mismo tiempo

De MSDN: "Cuando bWaitAll es FALSO, esta función comprueba los controladores en la matriz en orden comenzando con el índice 0, hasta que se señala uno de los objetos. Si se señalan varios objetos, la función devuelve el índice del primer identificador de la matriz cuyo objeto fue señalado. "

Entonces, ahora si hay múltiples objetos de señal, obtendré el índice del primero. ¿Tengo que hacer un bucle en mi matriz para ver si hay otros señalados?

Ahora mismo tengo un bucle que es a lo largo de las líneas de:

For (; ;) 
{ 
WaitForMultipleObjects(…) 
If (not failed) 
    Process object that called. 
    Remove the handle that signaled from the array. 
    Compact the arrary. 
} 

Respuesta

4

Por lo tanto, ahora si señal de múltiples objetos voy a obtener el índice de la primera. ¿Tengo que hacer un bucle en el a través de mi matriz para ver si hay otros señalados?

¿Por qué no simplemente retrocede en el Wait()? si se señalan varios objetos, se seguirán señalando cuando vuelvas. Por supuesto, si tienes un primer objeto que dispara muy rápidamente en la matriz de objetos de espera, morirá de hambre a los demás; lo que haces es ordenar tus objetos en la matriz de objetos de espera por frecuencia de disparo, siendo el menos frecuente el primero.

Por cierto, donde está usando un sinfin para(), podría usar un goto. Si realmente no está dejando un bucle, un goto incondicional expresa más adecuadamente su intención.

+0

Esta es efectivamente la solución utilizada. La clave que necesitaba saber era "si se señalaran varios objetos, se seguirán señalando cuando vuelvas". Si no tengo que preocuparme por la inanición, entonces mi solución original estaba bien. – Chris

+1

Sí. WaitForMultipleObjects() escanea el conjunto de identificadores de 0 en adelante y lo devuelve tan pronto como encuentra un identificador señalado. Solo ese primer asa encontrada se restablece al estado no señalado; los otros están intactos –

5

Sí. Una alternativa sería que podría hacer WaitForSingleObject (handle, 0) en cada identificador que devolverá inmediatamente e indicará si están señalados o no.

EDIT: Aquí está el pseudocódigo de ejemplo para lo que quiero decir:

ret = WaitForMultipleObjects() 
if (ret >= WAIT_OBJECT_0 && ret < WAIT_OBJECT_0 + (count)) 
{ 
    firstSignaled = ret - WAIT_OBJECT_0; 

    // handles[firstSignaled] guaranteed signalled!! 

    for (i = firstSignaled + 1; i < count; i++) 
    { 
     if (WaitForSingleObject(handles[i], 0) == WAIT_OBJECT_0) 
     { 
      // handles[i] Signaled! 
     } 
    } 
} 
+0

Sí hacer esto después de las WaitForMultipleObjects llaman –

+0

Gracias por la sugerencia, añade pseudocódigo para mostrar esto. – Michael

+0

El problema con esa respuesta es que básicamente has activado bWaitAll con ese WaitForSingleObject. No quiero esperar en todos los controles, solo servicio a los que han señalado. – Chris

3

Otra opción que podría tener es utilizar RegisterWaitForSingleObject. La idea es marcar el estado de evento señalado en una matriz secundaria de la función de devolución de llamada y luego señalar un evento maestro que se utiliza para activar el hilo primario (que llama a WaitForSingleObject en el evento maestro).

Obviamente tendrías que tener cuidado para asegurarte de que la matriz secundaria estuviera protegida del acceso por el hilo principal, pero funcionaría.

Cuestiones relacionadas