2010-12-01 5 views
6

Ho letto alcune fonti sui metodi corretti di bubbling di un messaggio da un thread a tutti gli altri thread per uscire con garbo (ogni thread esegue la propria routine di uscita). Di questi, mi è piaciuta l'idea di un booleano atomico globale che può essere contrassegnato da qualsiasi thread e tutti gli altri thread controllano questo flag per eseguire una routine di uscita: quando tutti i thread vengono uniti, il thread principale può uscire dall'applicazione.Uscita efficiente dall'applicazione multithread (specifiche)

I thread di calcolo puramente potrebbero essere gestiti in modo diverso, giusto?

È efficiente e sicuro? C'è un modo migliore per farlo?

Grazie!

risposta

1

In Windows, utilizzo QueueUserAPC per chiamare una funzione che genera un'eccezione, causando l'uscita dei thread in modo pulito.

ho scritto di più sui dettagli in questa risposta qui:

How do I guarantee fast shutdown of my win32 app?

In sintesi, ecco cosa succede:

Say filo A vuole terminare filo B (e poi C, D, ...)

  • thread a chiama QueueUserAPC(), passando la maniglia a filo B e l'indirizzo di una funzione che lancerà un'eccezione di classe di mio ThreadExit.
  • Il thread B viene eseguito normalmente fino a quando non chiama qualcosa che controlla le attese prevedibili. Forse WaitForSingleObjectEx, forse SleepEx, o qualcos'altro.
  • A questo punto, thread B esegue la funzione APC passata in precedenza, causando la generazione di un'eccezione nella Discussione B.
  • Tutti gli oggetti dello stack-allocati vengono automaticamente distrutti correttamente come l'eccezione fa filo B 'rilassarsi' il suo stack.
  • La funzione di filettatura più esterna della filettatura B attira l'eccezione.
  • Il thread B ora esce, probabilmente segnalando al thread A che è fatto.
+0

sembra intelligente, ma non riesco a scuotere la sensazione "questo è troppo hacky" ogni volta che lo leggo ... – Necrolis

+0

Devo ammettere che è non-portatile, ma la maggior parte delle altre soluzioni davvero restringono ciò che terze parti codice che puoi usare nei tuoi thread. Uso intensamente i thread per il networking e ho bisogno di librerie di rete di terze parti (ad esempio, Indy) che possano essere tranquillamente "arrestate". – Roddy

+0

Ancora non riesco a coglierlo, anche dalla spiegazione più dettagliata. Si utilizza QueueUserAPC quando si desidera uscire da un thread e questo alla fine richiama una funzione che genera un'eccezione e questa eccezione raggiunge ogni thread? Come vengono chiamati i distruttori e come appare la funzione di lancio delle eccezioni? (Tutta questa area di programmazione è nuova per me) Grazie! – oneminute

4

Non sono un fan dei thread che controllano le variabili di stato booleane (o altre) per sapere quando fare cosa, perché è uno spreco. I thread dovrebbero girare, controllando costantemente la variabile per vedere se ci sono nuove istruzioni. Questo brucia la CPU.

Un'opzione migliore è quella di creare un semaforo o in Windows un evento e avere tutti i thread in attesa. I thread possono dormire mentre non sono occupati e non rubano le fette di tempo da altri thread facendo il vero lavoro semplicemente per controllare una variabile.

+0

(Sono nuovo alla teoria parallela) La mia applicazione è esclusivamente Windows - Come i thread attendono un evento? Qualunque risorsa potresti indicarmi? – oneminute

+0

In Windows, si utilizzerà la famiglia di funzioni WaitForSingleObject() per attendere un evento creato da CreateEvent(). Link: http://msdn.microsoft.com/en-us/library/ms682396(VS.85).aspx –

+0

Sono un po 'confuso .. quindi in ogni thread controllo il ritorno di WaitForSingleObject (exitHandle, 0) per vedere se l'evento di uscita è segnalato? – oneminute