2009-06-01 18 views
13

Sé cómo utilizar la CPU y el uso de memoria para un proceso, pero me preguntaba cómo obtenerlo por nivel de subproceso. Si la mejor solución es hacer algo de P-Invocación, entonces eso está bien también.¿Cómo puedo obtener el uso de CPU y/o RAM de * THREAD * en C# (código administrado)?

Ejemplo de lo que necesito:

Thread myThread = Thread.CurrentThread; 

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

Console.WriteLine(GetThreadSpecificCpuUsage(myThread)); 

Respuesta

7

no se puede conseguir el uso de memoria por hilo porque la memoria es compartida entre todos los hilos en un proceso . ¿Cómo sabría el sistema operativo si asignó la memoria en un hilo y lo utilizó en otro? ¿Y qué significaría?

+0

Hay almacenamiento local de subprocesos. – CesarGon

+0

Pero normalmente TLS solo se usa para mantener una referencia a un objeto en la memoria compartida. – erikkallen

+0

No es el sistema operativo el que tiene que determinar el uso de un hilo, es el marco en sí mismo. –

10

Como se ha dicho, el uso de memoria no se puede responder, ya que es un atributo del proceso en su conjunto, pero el uso de la CPU:

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

Aquí es un sencillo programa que lanza 5 hilos que consumen diferentes cantidades de CPU y luego compara qué hilo administrado consume qué cantidad 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(); 
     } 
    } 
} 
} 

Tenga en cuenta que es posible que el CLR cambie el subproceso nativo bajo el que se ejecuta el subproceso administrado. Sin embargo, en la práctica no estoy seguro de qué tan a menudo sucede esto.

Cuestiones relacionadas