我正在贡献的一个应用程序,用于激活用C语言编写的组件。
C进程会进行一些非常繁重的运算,如果不小心可以真正打击你的CPU。
有没有办法为.NET生成的外部进程设置限制?
我已经看到this artivcle在操作系统级别设置硬内存限制,CPU有类似的东西吗?
答案 0 :(得分:9)
不在Windows中。您可以降低进程优先级,这将降低在CPU上调度有问题的进程并干扰其他(可能是更高优先级)应用程序的可能性。例如,来自http://dotnet-concepts-queries-interviews.blogspot.com/2007/05/how-to-set-process-priority-in-net.html:
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal;
请记住,如果您没有在框中运行任何其他内容,您可能希望此过程消耗所有可用的CPU。
如果它位于多处理器盒上,您还可以设置CPU亲和力,将处理限制为某些核心,并让其他核心的其他应用程序空闲。通常,OS在调度应用程序线程方面做得很好,因此设置进程优先级可能会有更好的整体结果。见How Can I Set Processor Affinity in .NET?
答案 1 :(得分:9)
我遇到了同样的问题。 我通过使用SetInformationJobObject Kernel32 Win Api和JOBOBJECT_CPU_RATE_CONTROL_INFORMATION结构来解决它。
我更大的问题是在c#中表示这个结构(使用“union”)。 希望我找到了这种结构的“单声道”描述。
[StructLayout(LayoutKind.Explicit)]
//[CLSCompliant(false)]
struct JOBOBJECT_CPU_RATE_CONTROL_INFORMATION
{
[FieldOffset(0)]
public UInt32 ControlFlags;
[FieldOffset(4)]
public UInt32 CpuRate;
[FieldOffset(4)]
public UInt32 Weight;
}
激活Cpu限制:
ControlFlags = 0x00000001 | 0x00000004;
CpuRate = percent of max usage * 100 (ex 50 * 100 for a 50% limit)
以下示例功能齐全。
我希望有帮助。
亲切的问候
-Thierry -
[DllImport("kernel32.dll", EntryPoint = "CreateJobObjectW", CharSet = CharSet.Unicode)]
public static extern IntPtr CreateJobObject(SecurityAttributes JobAttributes, string lpName);
[DllImport("kernel32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool AssignProcessToJobObject(IntPtr hJob, IntPtr hProcess);
[DllImport("kernel32.dll")]
static extern bool SetInformationJobObject(IntPtr hJob, JOBOBJECTINFOCLASS JobObjectInfoClass, IntPtr lpJobObjectInfo, uint cbJobObjectInfoLength);
public class SecurityAttributes
{
public int nLength;
public IntPtr pSecurityDescriptor;
public bool bInheritHandle;
public SecurityAttributes()
{
this.bInheritHandle = true;
this.nLength = 0;
this.pSecurityDescriptor = IntPtr.Zero;
}
}
public enum JOBOBJECTINFOCLASS
{
JobObjectAssociateCompletionPortInformation = 7,
JobObjectBasicLimitInformation = 2,
JobObjectBasicUIRestrictions = 4,
JobObjectEndOfJobTimeInformation = 6,
JobObjectExtendedLimitInformation = 9,
JobObjectSecurityLimitInformation = 5,
JobObjectCpuRateControlInformation = 15
}
[StructLayout(LayoutKind.Explicit)]
//[CLSCompliant(false)]
struct JOBOBJECT_CPU_RATE_CONTROL_INFORMATION
{
[FieldOffset(0)]
public UInt32 ControlFlags;
[FieldOffset(4)]
public UInt32 CpuRate;
[FieldOffset(4)]
public UInt32 Weight;
}
public enum CpuFlags
{
JOB_OBJECT_CPU_RATE_CONTROL_ENABLE = 0x00000001,
JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED = 0x00000002,
JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP = 0x00000004
}
/// <summary>
/// Launch the legacy application with some options set.
/// </summary>
static void DoExecuteProgramm()
{
// prepare the process to execute
var startInfo = new ProcessStartInfo();
. . . . .
// Start the process
var process = Process.Start(startInfo);
//Limit the CPU usage to 45%
var jobHandle = CreateJobObject(null, null);
AssignProcessToJobObject(jobHandle, process.Handle);
var cpuLimits = new JOBOBJECT_CPU_RATE_CONTROL_INFORMATION();
cpuLimits.ControlFlags = (UInt32)(CpuFlags.JOB_OBJECT_CPU_RATE_CONTROL_ENABLE | CpuFlags.JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP);
cpuLimits.CpuRate = 45 * 100; // Limit CPu usage to 45%
var pointerToJobCpuLimits = Marshal.AllocHGlobal(Marshal.SizeOf(cpuLimits));
Marshal.StructureToPtr(cpuLimits, pointerToJobCpuLimits, false);
if (!SetInformationJobObject(jobHandle, JOBOBJECTINFOCLASS.JobObjectCpuRateControlInformation, pointerToJobCpuLimits, (uint)Marshal.SizeOf(cpuLimits)))
{
Console.WriteLine("Error !");
}
}