Pooling dei thread

Esistono molte applicazioni che creano thread che trascorrono molto tempo nello stato di sospensione in attesa che si verifichi un evento. Altri thread possono entrare in uno stato di sospensione solo per essere svegliati periodicamente per eseguire il polling di una modifica o aggiornare le informazioni sullo stato. Il pooling di thread consente di usare i thread in modo più efficiente fornendo all'applicazione un pool di thread di lavoro gestiti dal sistema. Almeno un thread monitora lo stato di tutte le operazioni di attesa accodate al pool di thread. Al termine di un'operazione di attesa, un thread di lavoro del pool di thread esegue la funzione di callback corrispondente.

Questo argomento descrive l'API del pool di thread originale. L'API del pool di thread introdotta in Windows Vista è più semplice, affidabile, offre prestazioni migliori e offre maggiore flessibilità per gli sviluppatori. Per informazioni sull'API del pool di thread corrente, vedere Pool di thread.

È anche possibile accodare elementi di lavoro non correlati a un'operazione di attesa al pool di thread. Per richiedere che un elemento di lavoro venga gestito da un thread nel pool di thread, chiamare la funzione QueueUserWorkItem . Questa funzione accetta un parametro per la funzione che verrà chiamata dal thread selezionato dal pool di thread. Non è possibile annullare un elemento di lavoro dopo che è stato accodato.

I timer della coda timer e le operazioni di attesa registrate usano anche il pool di thread. Le funzioni di callback vengono accodate al pool di thread. È anche possibile usare la funzione BindIoCompletionCallback per pubblicare operazioni di I/O asincrone. Al termine dell'I/O , il callback viene eseguito da un thread del pool di thread.

Il pool di thread viene creato la prima volta che si chiama QueueUserWorkItem o BindIoCompletionCallback oppure quando un timer della coda timer o un'operazione di attesa registrata accoda una funzione di callback. Per impostazione predefinita, il numero di thread che è possibile creare nel pool di thread è di circa 500. Ogni thread usa le dimensioni dello stack predefinite e viene eseguito con la priorità predefinita.

Esistono due tipi di thread di lavoro nel pool di thread: I/O e non I/O. Un thread di lavoro di I/O è un thread che attende in uno stato di attesa di avviso. Gli elementi di lavoro vengono accodati ai thread di lavoro di I/O come chiamate asincrone di routine (APC). È consigliabile accodare un elemento di lavoro a un thread di lavoro di I/O se deve essere eseguito in un thread che attende in uno stato di avviso.

Un thread di lavoro non I/O attende le porte di completamento di I/O. L'uso di thread di lavoro non di I/O è più efficiente rispetto all'uso di thread di lavoro di I/O. Pertanto, è consigliabile usare thread di lavoro non di I/O quando possibile. I/O e thread di lavoro non di I/O non vengono chiusi se sono presenti richieste di I/O asincrone in sospeso. Entrambi i tipi di thread possono essere usati dagli elementi di lavoro che avviano richieste di completamento di I/O asincrone. Tuttavia, evitare di registrare richieste di completamento di I/O asincrone in thread di lavoro non I/O se potrebbero richiedere molto tempo per il completamento.

Per usare il pooling di thread, gli elementi di lavoro e tutte le funzioni chiamate devono essere thread-safe. Una funzione sicura non presuppone che il thread in esecuzione sia un thread dedicato o persistente. In generale, è consigliabile evitare di usare l'archiviazione locale del thread o effettuare una chiamata asincrona che richiede un thread permanente, ad esempio la funzione RegNotifyChangeKeyValue . Tuttavia, tali funzioni possono essere chiamate in un thread dedicato (creato dall'applicazione) o accodate a un thread di lavoro permanente (usando QueueUserWorkItem con l'opzione WT_EXECUTEINPERSISTENTTHREAD).

I/O di avviso

Chiamate di procedure asincrone

Porte di completamento di I/O

Pool di thread