2012-01-08 35 views
9

Quiero crear un programa que puede limitar el uso de la CPU de un proceso incluso cuando la computadora está inactiva. He hecho un programa que establece la prioridad del proceso, pero si la computadora está inactivo, el uso de la CPU puede alcanzar el 95%. El proceso contiene "elemento" es el proceso que yo quiero limitarCómo limitar el uso de la CPU de un proceso

private static readonly string[] RestrictedProcess = new[] { "element" }; 
    static void ProcessChecker(object o) 
    { 
     List<Process> resProc = new List<Process>(); 
     foreach(Process p in Process.GetProcesses()) 
     { 
      string s = p.ProcessName; 
      foreach(string rp in RestrictedProcess) 
      { 
       s = s.ToLower(); 
       if (s.Contains(rp)) 
        resProc.Add(p); 
      } 
     } 

     foreach(Process p in resProc) 
     { 
      p.PriorityBoostEnabled = false; 
      p.PriorityClass = ProcessPriorityClass.Idle; 
      p.MaxWorkingSet = new IntPtr(20000000); 
     } 

     SetPowerConfig(resProc.Count > 0 ? PowerOption.GreenComputing : PowerOption.Balanced); 
    } 

gracias de antemano ...

+0

Creo que su pregunta es específica del sistema operativo y debe etiquetarse como tal. Creo que su programa no compila con 'mono' en Linux. Entonces, su pregunta es más específica del sistema operativo que específica del idioma. –

+3

Si la computadora no está en uso (es decir, inactiva), ¿por qué es un problema que un proceso utilice el 95% de la CPU? –

+1

Si la elección es hacer * nada * y lograr un trabajo útil, ¿por qué el sistema operativo no hará nada? La forma de conseguir que un proceso use menos CPU es tener un proceso de mayor prioridad haciendo algo. –

Respuesta

20

Si el programa que desea limitar no el suyo es, hay varias opciones:

  • establecer la prioridad del proceso como Idle y no limitan el uso de la CPU como la CPU se debe utilizar tanto como posible en cualquier caso. Está bien tener tu CPU funcionando al 100% todo el tiempo si hay algo útil que hacer. Si la prioridad es idle, entonces el uso de la CPU de este proceso particular se reducirá si otro programa requiere CPU.
  • si su sistema es multi-core o multi-cpu, entonces es posible que desee configurar processor affinity. Esto le indicará a su programa que use solo el (los) procesador (es) que desea que use. Por ejemplo, si su programa es multiproceso y puede consumir el 100% de sus dos CPU, entonces configure su afinidad para usar solo una CPU. Su uso será entonces solo del 50%.
  • La peor opción, pero realmente utilizada por el 90% de los "programas limitadores de CPU" que encontrará en la web: mida el uso de CPU de un proceso y suspenda y reanude regularmente hasta que el uso de CPU alcance el valor querer.

Para suspender/reanudar un proceso que no es el suyo, deberá usar P/Invoke (y esto requiere tener acceso al proceso, de modo que si es Windows Vista o superior, cuide de UAC para derechos de administrador):

/// <summary> 
/// The process-specific access rights. 
/// </summary> 
[Flags] 
public enum ProcessAccess : uint 
{ 
    /// <summary> 
    /// Required to terminate a process using TerminateProcess. 
    /// </summary> 
    Terminate = 0x1, 

    /// <summary> 
    /// Required to create a thread. 
    /// </summary> 
    CreateThread = 0x2, 

    /// <summary> 
    /// Undocumented. 
    /// </summary> 
    SetSessionId = 0x4, 

    /// <summary> 
    /// Required to perform an operation on the address space of a process (see VirtualProtectEx and WriteProcessMemory). 
    /// </summary> 
    VmOperation = 0x8, 

    /// <summary> 
    /// Required to read memory in a process using ReadProcessMemory. 
    /// </summary> 
    VmRead = 0x10, 

    /// <summary> 
    /// Required to write to memory in a process using WriteProcessMemory. 
    /// </summary> 
    VmWrite = 0x20, 

    /// <summary> 
    /// Required to duplicate a handle using DuplicateHandle. 
    /// </summary> 
    DupHandle = 0x40, 

    /// <summary> 
    /// Required to create a process. 
    /// </summary> 
    CreateProcess = 0x80, 

    /// <summary> 
    /// Required to set memory limits using SetProcessWorkingSetSize. 
    /// </summary> 
    SetQuota = 0x100, 

    /// <summary> 
    /// Required to set certain information about a process, such as its priority class (see SetPriorityClass). 
    /// </summary> 
    SetInformation = 0x200, 

    /// <summary> 
    /// Required to retrieve certain information about a process, such as its token, exit code, and priority class (see OpenProcessToken, GetExitCodeProcess, GetPriorityClass, and IsProcessInJob). 
    /// </summary> 
    QueryInformation = 0x400, 

    /// <summary> 
    /// Undocumented. 
    /// </summary> 
    SetPort = 0x800, 

    /// <summary> 
    /// Required to suspend or resume a process. 
    /// </summary> 
    SuspendResume = 0x800, 

    /// <summary> 
    /// Required to retrieve certain information about a process (see QueryFullProcessImageName). A handle that has the PROCESS_QUERY_INFORMATION access right is automatically granted PROCESS_QUERY_LIMITED_INFORMATION. 
    /// </summary> 
    QueryLimitedInformation = 0x1000, 

    /// <summary> 
    /// Required to wait for the process to terminate using the wait functions. 
    /// </summary> 
    Synchronize = 0x100000 
} 

[DllImport("ntdll.dll")] 
internal static extern uint NtResumeProcess([In] IntPtr processHandle); 

[DllImport("ntdll.dll")] 
internal static extern uint NtSuspendProcess([In] IntPtr processHandle); 

[DllImport("kernel32.dll", SetLastError = true)] 
internal static extern IntPtr OpenProcess(
    ProcessAccess desiredAccess, 
    bool inheritHandle, 
    int processId); 

[DllImport("kernel32.dll", SetLastError = true)] 
[return: MarshalAs(UnmanagedType.Bool)] 
internal static extern bool CloseHandle([In] IntPtr handle); 

public static void SuspendProcess(int processId) 
{ 
    IntPtr hProc = IntPtr.Zero; 
    try 
    { 
     // Gets the handle to the Process 
     hProc = OpenProcess(ProcessAccess.SuspendResume, false, processId); 

     if (hProc != IntPtr.Zero) 
     { 
      NtSuspendProcess(hProc); 
     } 
    } 
    finally 
    { 
     // Don't forget to close handle you created. 
     if (hProc != IntPtr.Zero) 
     { 
      CloseHandle(hProc); 
     } 
    } 
} 
+2

Y esta es la razón por la que amo este sitio. Siempre aprendo muchas cosas interesantes. +1 para obtener información increíble – Demolishun

1

No sé exactamente el comando para C#, pero sería un comando que devuelve el control al sistema operativo. Creo que en C++ podría ser una demora o un sueño lo que hará eso. Entonces, la llamada equivalente en C# retrasará el código y devolverá los ciclos al sistema operativo.

+1

[' Thread.Sleep() '] (http://msdn.microsoft.com /en-us/library/system.threading.thread.sleep.aspx) es a lo que probablemente se está refiriendo. –

+0

El proceso que quiero limitar no es creado por mí .. Es solo un juego. –

+0

Si quieres ralentizar un juego, debes averiguar si la velocidad es de CPU o de reloj.Si está sincronizado con el reloj, será inútil limitar el uso de la CPU. –

Cuestiones relacionadas