2009-06-01 14 views
13

Je sais comment utiliser l'UC et l'utilisation de la mémoire pour un processus, mais je me demandais comment l'obtenir au niveau du thread. Si la meilleure solution est de faire un P-Invoke, alors c'est bien aussi.Comment puis-je obtenir l'utilisation du processeur et/ou l'utilisation de la RAM d'un * THREAD * en C# (code managé)?

Exemple de ce que je dois:

Thread myThread = Thread.CurrentThread; 

// some time later in some other function... 

Console.WriteLine(GetThreadSpecificCpuUsage(myThread)); 

Répondre

7

Vous ne pouvez pas obtenir l'utilisation de la mémoire par thread parce que la mémoire est partagée entre tous les threads d'un processus . Comment l'OS sait-il si vous avez alloué de la mémoire dans un thread et l'avez utilisé dans un autre. Et qu'est-ce que cela voudrait dire?

+0

Il y a du stockage local. – CesarGon

+0

Mais généralement TLS est seulement utilisé pour contenir une référence à un objet dans la mémoire partagée. – erikkallen

+0

Ce n'est pas l'OS celui qui doit déterminer l'utilisation d'un thread, c'est le framework lui-même. –

10

Comme l'a dit, l'utilisation de la mémoire ne peut pas répondre puisque c'est un attribut du processus dans son ensemble, mais l'utilisation du processeur:

Process p = Process.GetCurrentProcess(); // getting current running process of the app 
foreach (ProcessThread pt in p.Threads) 
{ 
    // use pt.Id/pt.TotalProcessorTime/pt.UserProcessorTime/pt.PrivilegedProcessorTime 
} 
1

Voici un programme simple qui lance 5 fils qui consomment des quantités différentes de CPU puis correspond à ce que le thread géré consomme quelle quantité de CPU.

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Runtime.InteropServices; 
using System.Threading; 

class Program 
{ 
[DllImport("Kernel32", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)] 
public static extern Int32 GetCurrentWin32ThreadId(); 

static void Main(string[] args) 
{ 
    Dictionary<int, Thread> threads = new Dictionary<int, Thread>(); 

    // Launch the threads 
    for (int i = 0; i < 5; i++) 
    { 
     Thread cpuThread = new Thread((start) => 
     { 
      lock (threads) 
      { 
       threads.Add(GetCurrentWin32ThreadId(), Thread.CurrentThread); 
      } 

      ConsumeCPU(20 * (int)start); 
     }); 
     cpuThread.Name = "T" + i; 
     cpuThread.Start(i); 
    } 

    // Every second wake up and see how much CPU each thread is using. 
    Thread monitoringThread = new Thread(() => 
     { 
      Stopwatch watch = new Stopwatch(); 
      watch.Start(); 

      while (true) 
      { 
       Thread.Sleep(1000); 
       Console.Write("\r"); 

       double totalTime = ((double)watch.ElapsedMilliseconds); 
       if (totalTime > 0) 
       { 
        Process p = Process.GetCurrentProcess(); 
        foreach (ProcessThread pt in p.Threads) 
        { 
         Thread managedThread; 
         if (threads.TryGetValue(pt.Id, out managedThread)) 
         { 
          double percent = (pt.TotalProcessorTime.TotalMilliseconds/totalTime); 
          Console.Write("{0}-{1:0.00} ", managedThread.Name, percent); 
         } 
        } 
       } 
      } 
     }); 
    monitoringThread.Start(); 
} 


// Helper function that generates a percentage of CPU usage 
public static void ConsumeCPU(int percentage) 
{ 
    Stopwatch watch = new Stopwatch(); 
    watch.Start(); 
    while (true) 
    { 
     if (watch.ElapsedMilliseconds > percentage) 
     { 
      Thread.Sleep(100 - percentage); 
      watch.Reset(); 
      watch.Start(); 
     } 
    } 
} 
} 

Notez qu'il est possible que le CLR modifie le thread natif dans lequel s'exécute le thread géré. Cependant, en pratique, je ne suis pas sûr de la fréquence à laquelle cela arrive.