2009-03-07 16 views
6

questo:Può un singolo SetEvent() attivare più WaitForSingleObject()

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

sembrerebbe non suggerire.

Ho tre processi di comunicazione tramite tubi. Processo A Crea un evento, Processo B & C ogni WaitForSingleObject (in un secondo thread).

Quindi ora abbiamo -TWO- Elabora ciascuno in attesa di un evento -SINGLE-.

Processo A attiva l'evento con SetEvent(), il processo B risponde, il processo C no.

Conclusione:

Ogni WaitForSingleObject() richiede un evento unico nel suo genere ... Corretto?

risposta

5

Utilizzare gli eventi di ripristino manuale per attivare più thread off di un singolo evento.

Here è un esempio che utilizza "reset manuale Evento" Bandiera

+0

Sfortunatamente non ho alcun controllo sul processo A, quindi non posso implementarlo. –

2

È possibile utilizzare i Evenets riarmo manuale e la funzione PulseEvent di rilasciare tutti i thread attualmente in attesa per l'evento.

Nota comunque che questo approccio è intrinsecamente vivace, in quanto non c'è modo di dire quali sono "i thread che stanno attualmente aspettando ...". È necessario utilizzare un meccanismo di sincronizzazione più affidabile se è necessaria la corrispondenza esatta degli eventi wakeup/2 wait.

+0

Non ho menzionato questo, ma non ho alcun controllo sul processo A, ma guarderò la funzione PulseEvent per riferimento futuro .. grazie. –

+0

Se è possibile modificare solo i thread B & C, sarebbe meglio risvegliare un thread dall'altro (cioè A -> B -> C) invece di provare a riattivare tutti i thread da A. BTW, se non si controllo A, dovresti avere un protocollo/interfaccia di blocco/attivazione e menzionarlo nella domanda. – jpalecek

+1

Non utilizzare PulseEvent, vedere http://blogs.msdn.com/oldnewthing/archive/2005/01/05/346888.aspx – CesarB

0

Spero che questo esempio può aiutare 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) se si crea un evento con lo stesso NAME, ogni setEvent segnalando tutti waitforsingleobjects

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

B) se si crea un evento con un numero unico NAME, lo invia solo il segnale all'handle di riferimento

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

Un evento può notificare più thread se si tratta di un evento di ripristino manuale. Un evento di reset automatico non può farlo. Se più di un battistrada è in attesa contemporaneamente di un evento di reset automatico e lo si imposta sullo stato segnalato, esiste solo un thread e lo si ripristina e il comportamento degli altri thread non sarà definito. Sebbene, dalla documentazione di Microsoft, possiamo presumere che uno e un solo thread usciranno mentre altri non uscirebbero sicuramente. Ad ogni modo, dobbiamo prendere in considerazione la seguente citazione: "Non assumere un ordine FIFO (first-in, first-out). Eventi esterni come gli APC in modalità kernel possono modificare l'ordine di attesa "Origine - https://msdn.microsoft.com/en-us/library/windows/desktop/ms682655(v=vs.85).aspx

La funzione CreateEvent ha il parametro bManualReset. Se è VERO, la funzione crea un oggetto evento di reset manuale, che richiede l'uso della funzione ResetEvent per impostare lo stato dell'evento su non segnalato. Se questo parametro è FALSE, la funzione crea un oggetto evento con reset automatico e il sistema reimposta automaticamente lo stato dell'evento su non segnalato dopo che è stato rilasciato un solo thread in attesa, cioè è uscito da una funzione come WaitForMultipleObjects o WaitForSigleObject, ma, come Ho scritto prima, solo un thread verrà notificato non tutti.

sui PulseEvent - è inaffidabile e non dovrebbe mai essere utilizzato - vedere https://msdn.microsoft.com/en-us/library/windows/desktop/ms684914(v=vs.85).aspx

Solo questi fili vengono avvisati da PulseEvent che si trovano nello stato di "attesa" al momento PulseEvent si chiama. Se sono in qualsiasi altro stato, non verranno notificati e non si potrà mai sapere con certezza quale sia lo stato del thread. Un thread in attesa su un oggetto di sincronizzazione può essere temporaneamente rimosso dallo stato di attesa da una chiamata di procedura asincrona in modalità kernel e quindi restituito allo stato di attesa al termine dell'APC. Se la chiamata a PulseEvent si verifica durante il periodo in cui il thread è stato rimosso dallo stato di attesa, il thread non verrà rilasciato perché PulseEvent rilascia solo quei thread che sono in attesa al momento della chiamata. Potete trovare maggiori informazioni sulla modalità kernel chiamate di procedura asincrona (APC) ai seguenti link:

È possibile ottenere ulteriori idee su auto- reimpostare gli eventi e gli eventi di ripristino manuale dal seguente articolo:

Problemi correlati