2012-01-08 15 views
9

Voglio creare un programma che possa limitare l'utilizzo della CPU di un processo anche quando il computer è inattivo .. Ho creato un programma che imposta la priorità del processo, ma se il computer è inattivo, l'utilizzo della CPU può raggiungere il 95%. Il processo contiene "elemento" è il processo che voglio limitareCome limitare l'utilizzo della CPU di un processo

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); 
    } 

grazie in anticipo ...

+0

Penso che la tua domanda sia specifica del sistema operativo e debba essere contrassegnata come tale. Credo che il tuo programma non si compili con 'mono' su Linux. Quindi la tua domanda è più specifica del sistema operativo rispetto alla lingua specifica. –

+3

Se il computer non è in uso (cioè inattivo), perché è un problema che un processo utilizza il 95% della CPU? –

+1

Se la scelta è tra fare * nothing * e realizzare un lavoro utile, perché il sistema operativo sceglierebbe di non fare nulla? Il modo in cui ottenere un processo per utilizzare meno CPU è avere un processo con priorità più alta facendo qualcosa. –

risposta

20

Se il programma che si desidera limitare non il vostro è, ci sono diverse opzioni:

  • impostare la priorità del processo di Idle e non limitano l'utilizzo della CPU come la CPU dovrebbe essere utilizzato il più possibile in ogni caso. Va bene avere la CPU sempre al 100% se c'è qualcosa di utile da fare. Se la priorità è idle, l'utilizzo della CPU di questo particolare processo verrà ridotto se un altro programma richiede CPU.
  • se il sistema è multi-core o multi-CPU, quindi è possibile impostare processor affinity. Questo dirà al tuo programma di usare solo il/i processore/i che tu vuoi che usi. Ad esempio, se il tuo programma è multithreaded e in grado di consumare il 100% delle tue due CPU, imposta la sua affinità per utilizzare solo una CPU. Il suo utilizzo sarà quindi solo del 50%.
  • La peggiore opzione, ma effettivamente utilizzata dal 90% dei "programmi di limitazione della CPU", si trova sul web: misurare l'utilizzo della CPU di un processo e sospenderlo e riprenderlo regolarmente fino a quando l'utilizzo della CPU va al valore che si volere.

Per sospendere/riprendere un processo che non è il tuo, dovrai utilizzare P/Invoke (e questo richiede di avere accesso al processo, quindi se sei Windows Vista o superiore, prenditi cura di UAC per i diritti di amministratore):

/// <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

Ed è per questo che adoro questo sito. Imparo sempre tante cose interessanti. +1 per alcune fantastiche informazioni! – Demolishun

1

non so il comando esatta per C#, ma sarebbe un comando che restituisce il controllo al sistema operativo. Penso che in C++ potrebbe essere un ritardo o un sonno che lo farà. Quindi la chiamata equivalente in C# che ritarderà il codice e restituirà i cicli al sistema operativo.

+1

[' Thread.Sleep() '] (http://msdn.microsoft.com /en-us/library/system.threading.thread.sleep.aspx) è ciò a cui ti stai probabilmente riferendo. –

+0

Il processo che voglio limitare non è stato creato da me .. È solo un gioco. –

+0

Se vuoi rallentare un gioco devi scoprire se la velocità è legata alla cpu o all'orologio.Se è legato all'orologio, sarà inutile limitare l'utilizzo della CPU. –

Problemi correlati