【发布时间】:2019-08-08 08:12:23
【问题描述】:
我希望我的进程不会超过 70% 的 CPU 使用率。我在这里找到了解决方案: How can I programmatically limit my program's CPU usage to below 70%? 。这是我试图从该链接使用的类:
public class ProcessManager
{
[Flags]
public enum ThreadAccess : int
{
TERMINATE = (0x0001),
SUSPEND_RESUME = (0x0002),
GET_CONTEXT = (0x0008),
SET_CONTEXT = (0x0010),
SET_INFORMATION = (0x0020),
QUERY_INFORMATION = (0x0040),
SET_THREAD_TOKEN = (0x0080),
IMPERSONATE = (0x0100),
DIRECT_IMPERSONATION = (0x0200)
}
[DllImport("kernel32.dll")]
static extern IntPtr OpenThread(ThreadAccess dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
[DllImport("kernel32.dll")]
static extern uint SuspendThread(IntPtr hThread);
[DllImport("kernel32.dll")]
static extern int ResumeThread(IntPtr hThread);
[DllImport("kernel32.dll")]
static extern int CloseHandle(IntPtr hThread);
public static void ThrottleProcess(int processId, double limit)
{
var process = Process.GetProcessById(processId);
var processName = process.ProcessName;
var p = new PerformanceCounter("Process", "% Processor Time", processName);
while (true)
{
var interval = 100;
Thread.Sleep(interval);
var currentUsage = p.NextValue() / Environment.ProcessorCount;
if (currentUsage < limit) continue; // Infinant loop ?
var suspensionTime = (currentUsage-limit) / currentUsage * interval;
SuspendProcess(processId);
Thread.Sleep((int)suspensionTime);
ResumeProcess(processId);
}
}
private static void SuspendProcess(int pid)
{
var process = Process.GetProcessById(pid);
if (process.ProcessName == string.Empty)
return;
foreach (ProcessThread pT in process.Threads)
{
IntPtr pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);
if (pOpenThread == IntPtr.Zero)
{
continue;
}
SuspendThread(pOpenThread);
CloseHandle(pOpenThread);
}
}
private static void ResumeProcess(int pid)
{
var process = Process.GetProcessById(pid);
if (process.ProcessName == string.Empty)
return;
foreach (ProcessThread pT in process.Threads)
{
IntPtr pOpenThread = OpenThread(ThreadAccess.SUSPEND_RESUME, false, (uint)pT.Id);
if (pOpenThread == IntPtr.Zero)
{
continue;
}
var suspendCount = 0;
do
{
suspendCount = ResumeThread(pOpenThread);
} while (suspendCount > 0);
CloseHandle(pOpenThread);
}
}
}
这段代码的作者在他的帖子下留下了评论说,使用 ThrottleProcess after Process.Start()。我做到了,但似乎在 Process 启动之后,它就进入了 ThrottleProcess 和 get stucks inside While 循环。而且我不知道该怎么办,也许它应该异步运行方法?就像 Process 应该独立于 Throttle 运行不是吗?
这是我的 Process 方法:
private string startProcess(string fileName, string args)
{
// Create Process manager
var ProcessManager = new ProcessManager();
string result = "";
Process p;
ProcessStartInfo psi = new ProcessStartInfo();
psi.FileName = fileName;
psi.Arguments = args;
psi.WorkingDirectory = "...\\TempFolder";
psi.UseShellExecute = false;
psi.CreateNoWindow = true;
psi.StandardOutputEncoding = System.Text.Encoding.UTF8;
psi.RedirectStandardInput = true;
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
p = Process.Start(psi);
// After it gots here, process get stuck inside while loop
ProcessManager.ThrottleProcess(p.Id , 1);
try
{
string output = p.StandardOutput.ReadToEnd();
p.WaitForExit();
if (p.ExitCode != 0)
throw new Exception("Program returned with error code " + p.ExitCode);
result = output.ToString();
}
catch (Exception ex)
{
result = ex.ToString();
}
finally
{
p.Close();
p.Dispose();
}
return result;
}
【问题讨论】:
-
检查 CPU 使用率不是您的工作。如果你的程序需要 CPU,那就去做吧。您的操作系统是需要管理资源的操作系统。几乎所有现代 CPU 和操作系统都在改变 CPU 的速度,这取决于所需的性能。
-
@user6537157 问题是我在服务器上的程序,一旦启动进程,它就会使用 100%,因此会减慢其他进程。
-
那你的程序还有其他问题。也许更好的是,您找出程序消耗如此多 CPU 时间的原因。但是不要在你的代码中建立一个“cpu 限制器”——它不会让你开心。
-
@user6537157 进程启动程序,而且那个程序不是我创建的,我怎么知道?
-
您想限制其他程序?更糟糕的是,您不知道其他程序对您的“限制”有何反应。我的提示:给应用程序降低 cpu 优先级并尝试调查问题(可能与原始开发人员交谈或使用其他软件)。
标签: c# asp.net asp.net-mvc process