微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

c# – 如何限制进程的CPU使用率

我想创建一个程序,即使在计算机空闲时也可以限制一个进程的cpu使用.
我已经制定了一个程序来设置进程的优先级,但如果计算机空闲,那么cpu的使用率可以达到95%.
该过程包含“元素”是我要限制的过程
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);
    }

提前致谢…

解决方法

如果您要限制的程序不是您的程序,则有几个选项:

>将进程优先级设置为空闲,并且不要限制cpu使用率,因为在任何情况下尽可能使用cpu.如果有一些有用的东西,那么让你的cpu运行100%是可行的.如果优先级空闲,则如果另一个程序需要cpu,则该特定进程的cpu使用率将会降低.
>如果您的系统是多核或多cpu,那么您可能需要设置processor affinity.这将告诉您的程序只使用您希望他使用的处理器.例如,如果您的程序是多线程的,并且能够消耗您的两个cpu的100%,则将其亲和力设置为仅使用一个cpu.那么他的使用量将只有50%.
>最差的选项,但实际使用的90%的“cpu限制程序”你会发现在网络上:衡量一个进程的cpu使用情况,并暂停和恢复它定期,直到cpu使用率达到你想要的值.

要暂停/恢复不是您的进程,您必须使用P / Invoke(并且这需要访问该进程,因此,如果您是Windows Vista或更高版本,请关注UAC以获取管理员权限):

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

原文地址:https://www.jb51.cc/csharp/93396.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐