13

Dopo aver letto Parallel.ForEach keeps spawning new threads sono ancora in dubbio se si tratti di un metodo corretto per il conteggio del numero di thread simultanei?Come contare la quantità di thread simultanei nell'applicazione .NET?

Quello che vedo è che il metodo conta il numero di iterazioni (loop) immesse simultaneamente ma non completate in Parallel.ForEach.
È sinonimo del numero di thread simultanei che trasmettono il numero corretto di thread eseguiti simultaneamente?
Io non sono uno specialista, ma posso immaginare che:

  • i fili possono essere riutilizzati, mentre la sua attività ha scambiato qualche parte per continuare in seguito.
  • teoricamente il filo agganciato per un'attività ciclo è mantenuto in raggruppamento filo dopo il completamento del ciclo, ma non riutilizzato per un'altra
  • O che sono le possibilità di distorsione della purezza di esperimento (conteggio di fili)?

In ogni caso, come contare direttamente la quantità di thread in esecuzione del processo .NET, preferibilmente in (C#) codice?

Aggiornamento:

Quindi, se a seguire il Jeppe Stig Nielsen's answer e utilizzare per il conteggio

directThreadsCount = Process.GetCurrentProcess().Threads.Count; 

poi uscita è, sia in uscita (threadsCount == 7) e Debug (threadsCount == 15) modalità è molto simile:

[Job 0 complete. 2 threads remaining but directThreadsCount == 7 
[Job 1 complete. 1 threads remaining but directThreadsCount == 7 
[Job 2 complete. 2 threads remaining but directThreadsCount == 7 
[Job 4 complete. 2 threads remaining but directThreadsCount == 7 
[Job 5 complete. 2 threads remaining but directThreadsCount == 7 
[Job 3 complete. 2 threads remaining but directThreadsCount == 7 
[Job 6 complete. 2 threads remaining but directThreadsCount == 7 
[Job 9 complete. 2 threads remaining but directThreadsCount == 7 
[Job 7 complete. 1 threads remaining but directThreadsCount == 7 
[Job 8 complete. 0 threads remaining but directThreadsCount == 7 
FINISHED 

Cioè, il numero di fili non sono mai diminuendo dicendo che the cited above method non è corretto mentre System.Diagnostics.ProcessThread"Class name is not valid at this point"

sono le mie conclusioni corrette e perché non possono essere utilizzati ProcessThread?

Il codice utilizzato di C# applicazione console:

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Linq; 
using System.Threading; 
using System.Threading.Tasks; 

namespace Edit4Posting 
{ 
public class Node 
{ 

    public Node Previous { get; private set; } 
    public Node(Node previous) 
    { 
    Previous = previous; 
    } 
    } 
    public class Edit4Posting 
    { 

    public static void Main(string[] args) 
    { 
     int concurrentThreads = 0; 
     int directThreadsCount = 0; 
     int diagThreadCount = 0; 

     var jobs = Enumerable.Range(0, 10); 
     Parallel.ForEach(jobs, delegate(int jobNr) 
     { 
     int threadsRemaining = Interlocked.Increment(ref concurrentThreads); 

     int heavyness = jobNr % 9; 

     //Give the processor and the garbage collector something to do... 
     List<Node> nodes = new List<Node>(); 
     Node current = null; 
     //for (int y = 0; y < 1024 * 1024 * heavyness; y++) 
     for (int y = 0; y < 1024 * 24 * heavyness; y++) 
     { 
      current = new Node(current); 
      nodes.Add(current); 
     } 
     //******************************* 
     //uncommenting next line gives: "Class name is not valid at this point" 
     //diagThreadCount=System.Diagnostics.ProcessThread 
     directThreadsCount = Process.GetCurrentProcess().Threads.Count; 
     //******************************* 
     threadsRemaining = Interlocked.Decrement(ref concurrentThreads); 
     Console.WriteLine(
      "[Job {0} complete. {1} threads remaining but directThreadsCount == {2}", 
      jobNr, threadsRemaining, directThreadsCount); 
     }); 
     Console.WriteLine("FINISHED"); 
     Console.ReadLine(); 
    } 
    } 
} 

risposta

34

Ci sono diversi tipi di thread, penso. le discussioni del sistema operativo per l'applicazione è in esecuzione, possono essere contati con:

int number = Process.GetCurrentProcess().Threads.Count; 

Sembra contare System.Diagnostics.ProcessThread istanze. Forse hai bisogno di contare un altro tipo di thread, come "thread gestiti", quindi non sono sicuro che la mia risposta sia ciò che cerchi.

+0

In teoria,' Thread's e 'ProcessThread's potrebbero essere diversi. In pratica, sono quasi sempre gli stessi. – svick

+0

@svick Un'applicazione console molto semplice che scrive la proprietà sopra, dà '4', a volte' 3'. Penserei che fosse un'applicazione a thread singolo. Quando la stessa applicazione è debugata (debugger allegato), il numero è molto più alto, come '12' o' 13'.In un'altra applicazione, se avvio molti nuovi thread con la classe 'System.Threading.Thread', il conteggio di' System.Diagnostics.ProcessThread' aumenta di circa il numero corretto. (Provato su Windows 7 a 64 bit.) –

11

Io non sono uno specialista, ma posso immaginare che i fili possono essere riutilizzati utilizzati durante la sua attività ha scambiato qualche parte.

No - a parte alcuni casi molto specifiche (che quasi certamente non c'è bisogno di preoccuparsi) le discussioni non sono uso reentrantly. Il thread verrà riutilizzato per eseguire un'altra iterazione (o un'altra attività) dopo l' l'iterazione corrente è stata completata, ma non verrà richiesto di fare qualcos'altro mentre il codice è in esecuzione.

Quindi il tuo approccio attuale è ragionevole, in pratica.

In ogni caso, come contare direttamente la quantità di thread in esecuzione in .NET?

È possibile cercare in perfmon, che lo grafico per voi. (Se il processo è sotto il tuo controllo, è più semplice avviare il processo ma attendere l'input, quindi aprire perfmon, aggiungere un contatore dalle opzioni "Process", selezionare "Thread Count" come contatore da aggiungere e limitare . al processo che ti interessa dall'elenco a discesa Hit OK, e quindi rendere il vostro processo di iniziare a lavorare)

EDIT:. per rispondere l'aggiornamento:

Cioè, il numero di thread sono non sempre diminuendo dicendo che il metodo sopra citato non è corretto

No, tutto ciò dimostra che il numero di thread attivi l'esecuzione del codice diminuisce, ma i thread vengono mantenuti in giro. È del tutto naturale per un pool di thread.

perché non è possibile utilizzare ProcessThread?

Lo stai semplicemente utilizzando improprio. Jeppe ha detto che il sistema è stato contando le istanze di ProcessThread mentre il vostro codice tenta di assegnare una classe ad una variabile:

diagThreadCount=System.Diagnostics.ProcessThread 

Questo è il codice semplicemente non valido. Il messaggio di errore mostra che il compilatore comprende che è il nome di un tipo, ma non puoi semplicemente assegnare un nome di tipo a una variabile.

+0

Jon, potresti dare un'occhiata alla mia domanda aggiornata? – Fulproof

+0

@Fulproof: fatto. Vedi la mia modifica. –

+0

'diagThreadCount = System.Diagnostics.ProcessThread' non è un codice completo, non ho potuto terminarlo poiché Intellisense e il compilatore danno un errore e si rifiuta di usare' ProcessThread' – Fulproof

Problemi correlati