Sincronizzazione di thread

Aggiornamento: novembre 2007

Durante la scrittura di un'applicazione con threading, può essere necessario sincronizzare determinati thread con altre parti del programma. La sincronizzazione consente di conciliare la natura non strutturata della programmazione multithread e l'ordine strutturato dell'elaborazione sincrona.

Le tecniche di sincronizzazione consentono di:

  • Controllare esplicitamente l'ordine di esecuzione del codice in tutti i casi in cui è necessario eseguire delle attività in base a sequenze specifiche

    -oppure-

  • Impedire il verificarsi di problemi derivanti dalla condivisione contemporanea della stessa risorsa da parte di due thread

È ad esempio possibile utilizzare la sincronizzazione per fare in modo che una routine di visualizzazione attenda il completamento di una routine di recupero di dati in esecuzione su un altro thread.

Tecniche di sincronizzazione

È possibile ottenere la sincronizzazione mediante due soluzioni: il polling e l'utilizzo degli oggetti di sincronizzazione. Per ulteriori informazioni sugli oggetti di sincronizzazione, vedere Tecniche avanzate di sincronizzazione.

Polling

Il polling è basato sulle verifiche ripetute dello stato di una chiamata asincrona dall'interno di un ciclo e costituisce la soluzione meno efficiente per la gestione dei thread, poiché comporta lo spreco di risorse, a causa delle verifiche ripetute dello stato delle varie proprietà del thread.

Durante il polling è ad esempio possibile utilizzare la proprietà IsAlive per verificare se un thread è stato terminato. È tuttavia necessario utilizzare con molta attenzione tale proprietà, poiché un thread attivo non è necessariamente in esecuzione.

Per ottenere informazioni più dettagliate sullo stato di un thread, è consigliabile utilizzare la proprietà ThreadState del thread. Poiché a ogni thread possono corrispondere più stati in un determinato momento, il valore memorizzato nella ThreadState può essere una combinazione dei valori presenti nell'enumerazione System.Threading.ThreadState. Si consiglia quindi di verificare con molta attenzione tutti gli stati rilevanti del thread durante il polling. Ad esempio, se lo stato di un thread indica che il thread non è Running, è possibile che sia stato completato, ma potrebbe anche essere semplicemente sospeso o in attesa.

Attesa della fine di un thread

Il metodo Thread.Join consente di stabilire se un thread è concluso prima di avviare una nuova attività. Il metodo Join attende la fine di un thread per un determinato intervallo di tempo. Se il thread viene completato prima del timeout, Join restituisce True. In caso contrario, restituisce False.

Risulta evidente che il polling comporta la rinuncia a molti dei vantaggi offerti dal multithreading, ma consente di ottenere il controllo sull'ordine di esecuzione dei thread. Il polling è decisamente poco efficiente, quindi non viene solitamente consigliato. Una soluzione più efficiente per il controllo dei thread utilizzerebbe il metodo Join. Join induce l'attesa di una routine chiamante fino alla conclusione del thread o fino a quando il tempo di chiamata raggiunge il timeout, se specificato. A tale metodo è stato assegnato il nome "join", poiché la creazione di un nuovo thread viene considerata come la creazione di un collegamento nel percorso di esecuzione. Il metodo Join consente di unire nuovamente percorsi di esecuzione distinti in un singolo thread.

Thread Set e Join

Figura 1 Threading

È necessario ricordare che Join è una chiamata sincrona o bloccante. Una volta chiamato Join o un metodo di attesa di un handle di attesa, la routine chiamante si interrompe e attende il segnale di completamento da parte del thread.

Sub JoinThreads()
    Dim Thread1 As New System.Threading.Thread(AddressOf SomeTask)
    Thread1.Start()
    Thread1.Join()      ' Wait for the thread to finish.
    MsgBox("Thread is done")
End Sub
Sub SomeTask()
    ' Insert code to perform a task here.
End Sub

Le semplici soluzioni illustrate per il controllo dei thread, estremamente utili per la gestione di un numero ridotto di thread, risultano tuttavia difficili da applicare a progetti di grandi dimensioni. Nella sezione Tecniche avanzate di sincronizzazione sono illustrate alcune tecniche che è possibile utilizzare per sincronizzare i thread.

Vedere anche

Concetti

Multithreading avanzato con Visual Basic

Parametri e valori restituiti per routine multithreading

Altre risorse

Multithreading in Visual Basic