Dan*_*ton 10 .net c# winapi unsafe
我正在贡献的一个应用程序启动用C编写的组件.
C进程做了一些相当重的运算,如果你不小心可以真正锤击你的CPU.
有没有办法为.NET生成的外部进程设置限制?
我已经看到这个artivcle在操作系统级别设置硬内存限制,CPU有类似的东西吗?
Thi*_*LG. 11
我有同样的问题.我通过使用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;
}
Run Code Online (Sandbox Code Playgroud)
要激活Cpu限制:
ControlFlags = 0x00000001 | 0x00000004;
CpuRate = percent of max usage * 100 (ex 50 * 100 for a 50% limit)
Run Code Online (Sandbox Code Playgroud)
以下示例功能齐全.
我希望这有帮助.
亲切的问候
-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 !");
}
}
Run Code Online (Sandbox Code Playgroud)
不在Windows中.您可以降低进程优先级,这将降低在CPU上调度有问题的进程并干扰其他(可能是更高优先级)应用程序的可能性.例如,来自http://dotnet-concepts-queries-interviews.blogspot.com/2007/05/how-to-set-process-priority-in-net.html:
Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.BelowNormal;
Run Code Online (Sandbox Code Playgroud)
请记住,如果您没有在盒子上运行任何其他东西,您可能希望此过程消耗所有可用的CPU.
如果它位于多处理器盒上,您还可以设置CPU亲和性,将处理限制为某些核心,并让其他核心的其他应用程序空闲.通常,OS在调度应用程序线程方面做得很好,因此设置进程优先级可能会有更好的整体结果.请参阅如何在.NET中设置处理器关联性?