2012-03-20 14 views
8

Cで書かれたコンポーネントを起動するアプリケーションです。.NETプロセスオブジェクトのCPU使用量を制限できますか?

Cプロセスではかなり重い処理が行われます。

.NETによって生成された外部プロセスに制限を設定する方法はありますか?

OSレベルでハード・メモリ制限を設定すると、this artivcleが表示されていますが、CPUにも同様のことがありますか?

+3

あなたは(私はそれもProcessStartInfo' 'でオプションかもしれないと思う)プロセスの優先度を変更することができます。それは実際にどれくらいのプロセッサ時間がかかるかを制限するものではありませんが、OSに他のプロセスを優先させるように指示します。 –

答えて

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?

+3

**この回答は間違っています**現在のバージョンのWindowsには注意が必要です。これは、Win2012/Win8の 'Job Object' APIを介して行うことができます。この質問がVista/Win7/Win2008で' NtSetInformationProcess' 'QUOTA_LIMITS_EX :: CPU_RATE_LIMIT'を使用できると答えた時点で可能です。あきらめる前に、他の回答やオンライン資料を見直してください。 さらに、優先度クラスを設定すると、CPU速度だけでなく、IO速度に影響を与えます。これは、IOスループットを低下させないという目的が意図しない影響を与える可能性があります。 –

+0

@ShaunWilsonこれを示す実用的なコードサンプルがありますか?私はまだこれを稼働させていない。 – i3arnon

7

私は同じ問題がありました。 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 !"); 
    } 
} 
+0

魅力的な、私はいつもWindows Jobオブジェクトを忘れていて、かなり役に立ちます。残念ながら、 'JobObjectCpuRateControlInformation'フラグはWin8以降でのみサポートされています。 –

+0

残念ながら、はい.... Windows 2012サーバーのプロセス管理に使用しました(セキュリティ要件)。 –

+0

あなたのコードをありがとう。このコードは私のために働くが、私はちょうど私が45%に制限CPuの使用を設定するのだろうが、それは54-50%を使用...あなたはなぜ知っているのですか? –

関連する問題