2012-01-08 38 views
9

Tôi muốn tạo chương trình có thể giới hạn việc sử dụng cpu của quá trình ngay cả khi máy tính không hoạt động .. Tôi đã tạo một chương trình ưu tiên quy trình, nhưng nếu máy tính nhàn rỗi, việc sử dụng cpu có thể đạt 95%. Quá trình này có chứa "nguyên tố" là quá trình mà tôi muốn giới hạnCách hạn chế sử dụng CPU của một quy trình

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

cảm ơn trước ...

+0

Tôi nghĩ rằng câu hỏi của bạn là hệ điều hành cụ thể và phải được gắn thẻ như vậy. Tôi tin rằng chương trình của bạn không biên dịch với 'mono' trên Linux. Vì vậy, câu hỏi của bạn là hệ điều hành cụ thể hơn ngôn ngữ cụ thể. –

+3

Nếu máy tính không được sử dụng (tức là nhàn rỗi), tại sao nó lại là một vấn đề mà một quá trình sử dụng 95% CPU? –

+1

Nếu sự lựa chọn là giữa việc * không có gì *, và đạt được công việc hữu ích, tại sao hệ điều hành lại chọn không làm gì? Cách để có được một quá trình sử dụng CPU ít hơn là phải có một quy trình ưu tiên cao hơn để làm điều gì đó. –

Trả lời

20

Nếu chương trình bạn muốn giới hạn không phải của bạn là, có một số lựa chọn:

  • thiết lập các quá trình ưu tiên như Idle và không giới hạn việc sử dụng CPU như CPU ​​nên được sử dụng càng nhiều càng tốt có thể trong mọi trường hợp. Bạn có thể chạy CPU 100% mọi lúc nếu có điều gì đó hữu ích để thực hiện. Nếu mức độ ưu tiên là idle, thì việc sử dụng CPU của quy trình cụ thể này sẽ bị giảm nếu chương trình khác yêu cầu CPU.
  • nếu hệ thống của bạn là đa lõi hoặc đa CPU, sau đó bạn có thể muốn đặt processor affinity. Điều này sẽ cho chương trình của bạn biết chỉ sử dụng (các) bộ xử lý mà bạn muốn anh ta sử dụng. Ví dụ, nếu chương trình của bạn là đa luồng và có thể tiêu thụ 100% của hai CPU của bạn, sau đó thiết lập mối quan hệ của mình để chỉ sử dụng một CPU. Cách sử dụng của anh ta sẽ chỉ là 50%.
  • Tùy chọn tồi tệ nhất nhưng thực sự được sử dụng bởi 90% "chương trình giới hạn CPU" bạn sẽ tìm thấy trên web: đo mức sử dụng CPU của một quy trình và Tạm dừng và tiếp tục lại thường xuyên cho đến khi sử dụng CPU muốn.

Để tạm dừng/tiếp tục quá trình không phải của bạn, bạn sẽ phải sử dụng P/Invoke (và điều này yêu cầu phải có quyền truy cập vào quy trình, vì vậy nếu bạn là Windows Vista trở lên, hãy chăm sóc UAC cho quyền quản trị):

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

Và đây là lý do tại sao tôi yêu trang web này. Tôi luôn học hỏi rất nhiều điều thú vị. 1 cho một số thông tin tuyệt vời! – Demolishun

1

Tôi không biết các lệnh chính xác cho C#, nhưng nó sẽ là một lệnh cho phép kiểm soát trở lại hệ điều hành. Tôi nghĩ rằng trong C + + nó có thể là một sự chậm trễ hoặc ngủ mà sẽ làm điều đó. Vì vậy, các cuộc gọi tương đương trong C# sẽ trì hoãn mã và cung cấp cho chu kỳ trở lại hệ điều hành.

+1

[' Thread.Sleep() '] (http://msdn.microsoft.com /en-us/library/system.threading.thread.sleep.aspx) là những gì bạn có thể đang đề cập đến. –

+0

Quá trình mà tôi muốn giới hạn không phải do tôi tạo ra .. Nó chỉ là một trò chơi. –

+0

Nếu bạn muốn làm chậm một trò chơi, bạn cần phải tìm hiểu xem tốc độ là cpu hoặc đồng hồ bị ràng buộc.Nếu nó là đồng hồ bị ràng buộc nó sẽ là vô ích để hạn chế sử dụng CPU. –

Các vấn đề liên quan