■ 프로세스 CPU 사용률을 제한하는 방법을 보여준다.
▶ SecurityAttribute.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
using System; namespace TestProject { /// <summary> /// 보안 어트리뷰트 /// </summary> public class SecurityAttribute { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// 길이 /// </summary> public int Length; /// <summary> /// 보안 설명자 /// </summary> public IntPtr SecurityDescriptor; /// <summary> /// 상속 핸들 /// </summary> public bool InheritHandle; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - SecurityAttribute() /// <summary> /// 생성자 /// </summary> public SecurityAttribute() { Length = 0; SecurityDescriptor = IntPtr.Zero; InheritHandle = true; } #endregion } } |
▶ ControlFlag.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
namespace TestProject { /// <summary> /// 컨트롤 플래그 /// </summary> public enum ControlFlag { /// <summary> /// JOB_OBJECT_CPU_RATE_CONTROL_ENABLE /// </summary> JOB_OBJECT_CPU_RATE_CONTROL_ENABLE = 0x00000001, /// <summary> /// JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED /// </summary> JOB_OBJECT_CPU_RATE_CONTROL_WEIGHT_BASED = 0x00000002, /// <summary> /// JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP /// </summary> JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP = 0x00000004 } } |
▶ JobObjectInformationClass.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
namespace TestProject { /// <summary> /// 작업 객체 정보 클래스 /// </summary> public enum JobObjectInformationClass { /// <summary> /// JobObjectAssociateCompletionPortInformation /// </summary> JobObjectAssociateCompletionPortInformation = 7, /// <summary> /// JobObjectBasicLimitInformation /// </summary> JobObjectBasicLimitInformation = 2, /// <summary> /// JobObjectBasicUIRestrictions /// </summary> JobObjectBasicUIRestrictions = 4, /// <summary> /// JobObjectEndOfJobTimeInformation /// </summary> JobObjectEndOfJobTimeInformation = 6, /// <summary> /// JobObjectExtendedLimitInformation /// </summary> JobObjectExtendedLimitInformation = 9, /// <summary> /// JobObjectSecurityLimitInformation /// </summary> JobObjectSecurityLimitInformation = 5, /// <summary> /// JobObjectCpuRateControlInformation /// </summary> JobObjectCpuRateControlInformation = 15 } } |
▶ JOBOBJECT_CPU_RATE_CONTROL_INFORMATION.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
using System; using System.Runtime.InteropServices; namespace TestProject { /// <summary> /// 작업 객체 CPU 사용률 제어 정보 /// </summary> [StructLayout(LayoutKind.Explicit)] public struct JOBOBJECT_CPU_RATE_CONTROL_INFORMATION { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Public #region Field /// <summary> /// 컨트롤 플래그 /// </summary> [FieldOffset(0)] public UInt32 ControlFlag; /// <summary> /// CPU 사용률 /// </summary> [FieldOffset(4)] public UInt32 CPURate; /// <summary> /// 가중치 /// </summary> [FieldOffset(4)] public UInt32 Weight; #endregion } } |
▶ ProcessHelper.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
using System; using System.Diagnostics; using System.Runtime.InteropServices; namespace TestProject { /// <summary> /// 프로세스 헬퍼 /// </summary> public class ProcessHelper { //////////////////////////////////////////////////////////////////////////////////////////////////// Import ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 작업 객체 생성하기 - CreateJobObject(securityAttribute, name) /// <summary> /// 작업 객체 생성하기 /// </summary> /// <param name="securityAttribute">보안 어트리뷰트</param> /// <param name="name">명칭</param> /// <returns>작업 객체 핸들</returns> [DllImport("kernel32.dll", EntryPoint = "CreateJobObjectW", CharSet = CharSet.Unicode)] private static extern IntPtr CreateJobObject(SecurityAttribute securityAttribute, string name); #endregion #region 프로세스를 작업 객체에 할당하기 - AssignProcessToJobObject(jobHandle, processHandle) /// <summary> /// 프로세스를 작업 객체에 할당하기 /// </summary> /// <param name="jobHandle">작업 객체 핸들</param> /// <param name="processHandle">프로세스 핸들</param> /// <returns>처리 결과</returns> [DllImport("kernel32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool AssignProcessToJobObject(IntPtr jobHandle, IntPtr processHandle); #endregion #region 정보 작업 객체 설정하기 - SetInformationJobObject(jobHandle, jobObjectInformationClass, jobObjectInformationHandle, jobObjectInformationLength) /// <summary> /// 정보 작업 객체 설정하기 /// </summary> /// <param name="jobHandle">작업 핸들</param> /// <param name="jobObjectInformationClass">작업 객체 정보 클래스</param> /// <param name="jobObjectInformationHandle">작업 객체 정보 핸들</param> /// <param name="jobObjectInformationLength">작업 객체 정보 길이</param> /// <returns>처리 결과</returns> [DllImport("kernel32.dll")] private static extern bool SetInformationJobObject(IntPtr jobHandle, JobObjectInformationClass jobObjectInformationClass, IntPtr jobObjectInformationHandle, uint jobObjectInformationLength); #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Public #region 프로세스 설정하기 - SetProcess(process, limitUsage) /// <summary> /// 프로세스 설정하기 /// </summary> /// <param name="process">프로세스</param> /// <param name="limitUsage">제한 사용률 (예 : 45 (45%))</param> /// <returns>처리 결과</returns> public static bool SetProcess(Process process, uint limitUsage) { IntPtr jobHandle = CreateJobObject(null, null); AssignProcessToJobObject(jobHandle, process.Handle); JOBOBJECT_CPU_RATE_CONTROL_INFORMATION information = new JOBOBJECT_CPU_RATE_CONTROL_INFORMATION(); information.ControlFlag = (uint)(ControlFlag.JOB_OBJECT_CPU_RATE_CONTROL_ENABLE | ControlFlag.JOB_OBJECT_CPU_RATE_CONTROL_HARD_CAP); information.CPURate = limitUsage * 100; IntPtr informationHandle = Marshal.AllocHGlobal(Marshal.SizeOf(information)); Marshal.StructureToPtr(information, informationHandle, false); bool result = SetInformationJobObject ( jobHandle, JobObjectInformationClass.JobObjectCpuRateControlInformation, informationHandle, (uint)Marshal.SizeOf(information) ); return result; } #endregion } } |
▶ Program.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
using System; using System.Diagnostics; namespace TestProject { /// <summary> /// 프로그램 /// </summary> class Program { //////////////////////////////////////////////////////////////////////////////////////////////////// Field ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region Field /// <summary> /// 프로세스 /// </summary> private static Process _process = null; #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Static //////////////////////////////////////////////////////////////////////////////// Private #region 프로그램 시작하기 - Main() /// <summary> /// 프로그램 시작하기 /// </summary> private static void Main() { _process = new Process(); _process.EnableRaisingEvents = false; _process.StartInfo.FileName = "TestWorker.exe"; _process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; _process.Start(); ProcessHelper.SetProcess(_process, 30); Console.ReadKey(false); _process.Kill(); } #endregion } } |