Discussione vs ThreadPool


137

Qual è la differenza tra l'utilizzo di un nuovo thread e l'utilizzo di un thread dal pool di thread? Quali sono i vantaggi in termini di prestazioni e perché dovrei prendere in considerazione l'utilizzo di un thread dal pool anziché di uno che ho creato esplicitamente? Sto pensando specificamente a .NET qui, ma gli esempi generali vanno bene.

Risposte:


110

Il pool di thread fornirà vantaggi per operazioni frequenti e relativamente brevi entro il 2005

  • Riutilizzare i thread che sono già stati creati anziché crearne di nuovi (un processo costoso)
  • Limitare la velocità di creazione del thread quando c'è un'esplosione di richieste per nuovi elementi di lavoro (credo che questo sia solo in .NET 3.5)

    • Se si mettono in coda 100 attività del pool di thread, verranno utilizzati solo tutti i thread già creati per soddisfare queste richieste (ad esempio 10). Il pool di thread effettuerà controlli frequenti (credo ogni 500ms in 3.5 SP1) e se ci sono attività in coda, creerà un nuovo thread. Se le tue attività sono veloci, il numero di nuovi thread sarà ridotto e riutilizzando i 10 thread circa per le attività brevi sarà più veloce della creazione di 100 thread in anticipo.

    • Se il carico di lavoro ha costantemente un numero elevato di richieste di pool di thread in arrivo, il pool di thread si sintonizzerà automaticamente sul carico di lavoro creando più thread nel pool con il processo precedente in modo che vi sia un numero maggiore di thread disponibili per elaborare le richieste

    • controlla qui per informazioni più approfondite su come funziona il pool di thread sotto il cofano

La creazione di un nuovo thread da soli sarebbe più appropriata se il lavoro fosse relativamente lungo (probabilmente circa un secondo o due, ma dipende dalla situazione specifica)

@Krzysztof - I thread del pool di thread sono thread in background che si interromperanno al termine del thread principale. I thread creati manualmente sono in primo piano per impostazione predefinita (continueranno a funzionare dopo che il thread principale è terminato), ma possono essere impostati in background prima di chiamare Avvia su di essi.


5
L'unica cosa che mi chiedo è la seguente dichiarazione da MSDN ( msdn.microsoft.com/en-us/library/1c9txz50.aspx ) "Un thread in background viene eseguito solo quando il numero di thread in primo piano in esecuzione è inferiore al numero di processori . ". Ciò significa che quando si divide il lavoro tra i core, i thread in primo piano hanno la priorità?
cdiggins,

1
➤ Non è possibile interrompere o interrompere un thread dal pool di thread. ➤ Non è possibile unire un thread dal pool di thread. Per raggiungere questo obiettivo, è necessario utilizzare alcuni altri meccanismi
Zinov

14

Il threadpool gestito .NET: -

  • Si dimensiona in base al carico di lavoro corrente e all'hardware disponibile
  • Contiene thread di lavoro e thread delle porte di completamento (che sono specificamente utilizzati per servire l'IO)
  • È ottimizzato per un gran numero di operazioni di breve durata

Esistono altre implementazioni del pool di thread che potrebbero essere più appropriate per operazioni di lunga durata.

In particolare, utilizzare un pool di thread per impedire all'app di creare troppi thread. La caratteristica più importante di un threadpool è la coda di lavoro. Cioè, una volta che la macchina è sufficientemente occupata, il pool di thread accoderà le richieste anziché generare immediatamente più thread.

Quindi, se creerai un numero limitato e limitato di thread, creali tu stesso. Se non riesci a determinare anticipatamente quanti thread potrebbero essere creati (ad es. Sono creati in risposta all'IO in entrata) e il loro lavoro avrà vita breve, usa il threadpool. Se non sai quanti, ma il loro lavoro durerà a lungo, non c'è nulla nella piattaforma che ti possa aiutare, ma potresti essere in grado di trovare implementazioni di thread pool alternative adatte.


In .NET, puoi usare le porte di completamento senza il pool di thread? Supponevo che i metodi di I / O asincroni fossero l'unico modo (in .NET) e che usassero il pool di thread
Karg,

10

anche

new Thread().Start()

genera un thread in primo piano che non morirà se chiudi il programma. I thread ThreadPool sono thread in background che muoiono quando chiudi l'app.


11
Puoi sempre impostare un thread sullo sfondo. Sono in primo piano per impostazione predefinita.
Kris Erickson,

3
nemo: var t = new Thread (...); t.BackgroundThread = true; t.Start ();
Ricardo Amores,

18
Chiarimento sul termine "programma". Un'applicazione desktop viene eseguita in un processo e ha almeno un thread in primo piano che gestisce l'interfaccia utente. Quel processo continuerà a funzionare finché ha thread in primo piano. Quando chiudi un'applicazione desktop, il thread dell'interfaccia utente in primo piano si interrompe, ma non hai necessariamente interrotto il processo se ha altri thread in primo piano.
G-Wiz,

8

Ero curioso dell'utilizzo delle risorse relative per questi e ho eseguito un benchmark sul mio laptop Intel i5 dual-core 2012 utilizzando la versione .net 4.0 build su Windows 8. I pool di thread hanno impiegato in media 0,035 ms per iniziare dove i thread hanno impiegato in media 5,06 SM. In altre parole, Thread nel pool è stato avviato circa 300 volte più veloce per un numero elevato di thread di breve durata. Almeno nell'intervallo testato (100-2000), il tempo totale per thread sembrava piuttosto costante.

Questo è il codice che è stato confrontato:

    for (int i = 0; i < ThreadCount; i++) {
        Task.Run(() => { });
    }

    for (int i = 0; i < ThreadCount; i++) {
        var t = new Thread(() => { });
        t.Start();
    }

inserisci qui la descrizione dell'immagine


5
Penso che sia perché il ThreadPool riutilizza i thread creati invece di crearne di nuovi (che è molto costoso)
fabriciorissetto


1

L'archiviazione locale dei thread non è una buona idea con i pool di thread. Dà ai thread una "identità"; non tutti i thread sono più uguali. Ora i pool di thread sono particolarmente utili se hai solo bisogno di un gruppo di thread identici, pronti a fare il tuo lavoro senza sovraccarico di creazione.


1

Se hai bisogno di molti thread, probabilmente vuoi usare un ThreadPool. Riutilizzano i thread risparmiando il sovraccarico della creazione del thread.

Se hai solo bisogno di un thread per fare qualcosa, Thread è probabilmente il più semplice.


1

L'esigenza primaria dei thread dello stagno è di gestire brevi compiti che dovrebbero essere completati quasi all'istante. I gestori di interrupt di processo vengono spesso eseguiti in un contesto di stacking che non sarebbe adatto per il codice non kernel, ma un gestore di interrupt di processo potrebbe scoprire che un callback di completamento I / O in modalità utente deve essere eseguito il prima possibile. Creare un nuovo thread allo scopo di eseguire una cosa del genere sarebbe eccessivo. Avere alcuni thread pre-creati che possono essere inviati per eseguire callback di completamento I / O o altre cose simili è molto più efficiente.

Un aspetto chiave di tali thread è che se i metodi di completamento dell'I / O si completano sempre essenzialmente istantaneamente e non si bloccano mai, e il numero di tali thread che attualmente eseguono tali metodi è almeno uguale al numero di processori, l'unico modo per qualsiasi altro thread potrebbe essere eseguito prima che uno dei metodi sopra menzionati finisca se uno degli altri metodi si blocchi o il suo tempo di esecuzione supera un normale intervallo di threading; nessuno di questi dovrebbe accadere molto spesso se il pool di thread viene utilizzato come previsto.

Se non ci si può aspettare che un metodo esca entro 100 ms o più da quando inizia l'esecuzione, il metodo dovrebbe essere eseguito in qualche modo diverso dal pool di thread principale. Se uno ha molte attività da svolgere che richiedono molta CPU ma non si bloccano, può essere utile inviarle utilizzando un pool di thread dell'applicazione (uno per core della CPU) che è separato dal threadpool "principale", poiché più thread che core saranno controproducenti quando si eseguono attività ad alta intensità di CPU non bloccanti. Se, tuttavia, un metodo impiegherà un secondo o più per essere eseguito e trascorrerà la maggior parte del suo tempo bloccato, il metodo dovrebbe probabilmente essere eseguito in un thread dedicato e quasi certamente non dovrebbe essere eseguito in un thread main-threadpool. Se un'operazione di lunga durata deve essere attivata da qualcosa come un callback I / O,


0

In generale (non ho mai usato .NET), un pool di thread verrebbe utilizzato per scopi di gestione delle risorse. Consente di configurare i vincoli nel software. Potrebbe anche essere fatto per motivi di prestazioni, poiché la creazione di nuovi thread potrebbe essere costosa.

Potrebbero inoltre esserci motivi specifici del sistema. In Java (di nuovo non so se questo si applica a .NET), il gestore dei thread può applicare variabili specifiche del thread mentre ogni thread viene estratto dal pool e disinserirli quando vengono restituiti (modo comune per passare qualcosa come un'identità).

Vincolo di esempio: ho solo 10 connessioni db, quindi consentirei solo 10 thread di lavoro per accedere al database.

Questo non significa che non dovresti creare i tuoi thread, ma ci sono condizioni in cui ha senso usare un pool.


0

L'uso di un pool è una buona idea, se non si conosce o non si può controllare il numero di thread che verranno creati.

Basta avere un problema con un modulo che utilizza il thread per aggiornare un campo da un database in un evento con posizione modificata di un controllo elenco (evitare il blocco). Il mio utente ha impiegato 5 minuti per avere un errore dal database (troppe connessioni con Access) perché stava cambiando la posizione dell'elenco troppo velocemente ...

So che esiste un altro modo per risolvere il problema di base (incluso non usare l'accesso) ma il pooling è un buon inizio.


0

Discussione :

  1. La creazione di un thread è molto più lenta rispetto all'utilizzo del pool di thread.
  2. È possibile modificare la priorità di un thread.
  3. Il numero massimo di thread in un processo relativo alle risorse.
  4. Il thread è a livello di sistema operativo e controllato dal sistema operativo.
  5. L'uso di Thread è un'opzione migliore quando l'attività ha una durata relativamente lunga

Pool di thread :

  1. L'esecuzione di un thread nel pool di thread è molto più rapida della creazione diretta di un thread.
  2. Non è possibile modificare la priorità dell'esecuzione di un thread in base al pool di thread.
  3. Esiste un solo pool di thread per processo.
  4. Il pool di thread è gestito da CLR.
  5. Il pool di thread è utile per operazioni di breve durata.
  6. Il numero di thread nel pool di thread è correlato al carico dell'applicazione.
  7. Le attività TPL vengono eseguite in base al pool di thread
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.