첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
유용한 소스 코드가 있으면 icodebroker@naver.com으로 보내주시면 감사합니다.
블로그 자료는 자유롭게 사용하세요.

728x90
반응형

TestSolution.zip
다운로드

 

[TestProject 프로젝트]

▶ MainForm.cs

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Windows.Forms;

namespace TestProject
{
    /// <summary>
    /// 메인 폼
    /// </summary>
    public partial class MainForm : Form
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 반복 작업자
        /// </summary>
        private RepeatWorker statusWorker = null;

        /// <summary>
        /// 성능 헬퍼
        /// </summary>
        private PerformanceHelper performanceHelper = new PerformanceHelper();

        /// <summary>
        /// CPU 사용률 리스트
        /// </summary>
        private List<float> cpuRateList = new List<float>();

        /// <summary>
        /// 프로세스 큐
        /// </summary>
        private Queue<Process> processQueue = new Queue<Process>();

        /// <summary>
        /// 프로세스 CPU 사용률
        /// </summary>
        private float processCPURate = 10;

        /// <summary>
        /// 타겟 프로세스 카운트
        /// </summary>
        private int targetProcessCount = 3;

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
        ////////////////////////////////////////////////////////////////////////////////////////// Public

        #region 생성자 - MainForm()

        /// <summary>
        /// 생성자
        /// </summary>
        public MainForm()
        {
            InitializeComponent();

            this.startButton.Click += startButton_Click;
        }

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Private

        #region 프로세스 구하기 - GetProcess()

        /// <summary>
        /// 프로세스 구하기
        /// </summary>
        /// <returns>프로세스</returns>
        private Process GetProcess()
        {
            Process process = new Process();

            process.EnableRaisingEvents   = false;
            process.StartInfo.FileName    = "TestWorker.exe";
            process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

            return process;
        }

        #endregion
        #region 상태 처리하기 - ProcessStatus(parameter)

        /// <summary>
        /// 상태 처리하기
        /// </summary>
        /// <param name="parameter">매개 변수</param>
        private void ProcessStatus(object parameter)
        {
            float currentCPURate = (uint)performanceHelper.GetCPURate();

            Console.WriteLine("CURRENT CPU RATE {0}", currentCPURate);

            this.cpuRateList.Add(currentCPURate);

            if(this.cpuRateList.Count > 30)
            {
                this.cpuRateList.RemoveAt(0);
            }

            float averageCPURate = this.cpuRateList.Average();

            Console.WriteLine("AVERAGE CPU RATE {0}", averageCPURate);

            int averageProcessCount = (int)(averageCPURate / this.processCPURate);

            Console.WriteLine("AVERAGE PROCESS COUNT {0}", averageProcessCount);

            if(this.targetProcessCount > averageProcessCount)
            {
                int processCount = this.targetProcessCount - averageProcessCount;

                int differenceProcessCount = processCount - this.processQueue.Count;

                for(int i = 0; i < differenceProcessCount; i++)
                {
                    Process process = GetProcess();

                    process.Start();

                    ProcessHelper.SetProcess(process, (uint)this.processCPURate);

                    this.processQueue.Enqueue(process);
                }
            }
            else
            {
                int processCount = averageProcessCount - this.targetProcessCount;

                while(this.processQueue.Count > 0 && processCount > 0)
                {   
                    Process process = this.processQueue.Dequeue();

                    if(process != null)
                    {
                        process.Kill();
                    }

                    processCount--;
                }
            }

            Console.WriteLine("PROCESS QUEUE COUNT {0}", this.processQueue.Count);
        }

        #endregion
        #region 시작하기 버튼 클릭시 처리하기 - startButton_Click(sender, e)

        /// <summary>
        /// 시작하기 버튼 클릭시 처리하기
        /// </summary>
        /// <param name="sender">이벤트 발생자</param>
        /// <param name="e">이벤트 인자</param>
        private void startButton_Click(object sender, EventArgs e)
        {
            if(this.startButton.Text == "시작하기")
            {
                string processCPURateString = this.processCPURateTextBox.Text.Trim();

                try
                {
                    this.processCPURate = Convert.ToSingle(processCPURateString);
                }
                catch(Exception)
                {
                    MessageBox.Show("프로세스당 CPU 사용률 (%)를 정확히 입력해 주시기 바랍니다.");

                    this.processCPURateTextBox.SelectAll();

                    this.processCPURateTextBox.Focus();

                    return;
                }

                string targetProcessCountString = this.targetProcessCountTextBox.Text.Trim();

                this.processCPURateTextBox.ReadOnly     = true;
                this.targetProcessCountTextBox.ReadOnly = true;

                try
                {
                    this.targetProcessCount = Convert.ToInt32(targetProcessCountString);
                }
                catch(Exception)
                {
                    MessageBox.Show("타겟 프로세스 수를 정확히 입력해 주시기 바랍니다.");

                    this.targetProcessCountTextBox.SelectAll();

                    this.targetProcessCountTextBox.Focus();

                    return;
                }

                Action<object> action = new Action<object>(ProcessStatus);

                this.statusWorker = new RepeatWorker(action, null, 1000);

                this.statusWorker.Start();

                this.startButton.Text = "중단하기";
            }
            else
            {
                this.statusWorker.Stop();

                this.statusWorker = null;

                while(this.processQueue.Count > 0)
                {
                    Process process = this.processQueue.Dequeue();

                    process.Kill();
                }

                this.processCPURateTextBox.ReadOnly     = false;
                this.targetProcessCountTextBox.ReadOnly = false;

                this.startButton.Text = "시작하기";
            }
        }

        #endregion
    }
}

 

[TestWorker 프로젝트]

▶ Program.cs

using System;
using System.Threading;

namespace TestWorker
{
    /// <summary>
    /// 프로그램
    /// </summary>
    class Program
    {
        //////////////////////////////////////////////////////////////////////////////////////////////////// Field
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region Field

        /// <summary>
        /// 난수기
        /// </summary>
        private static Random _random = new Random();

        #endregion

        //////////////////////////////////////////////////////////////////////////////////////////////////// Method
        ////////////////////////////////////////////////////////////////////////////////////////// Static
        //////////////////////////////////////////////////////////////////////////////// Private

        #region 스레드 처리하기 - ProcessThread()

        /// <summary>
        /// 스레드 처리하기
        /// </summary>
        public static void ProcessThread()
        {
            long number = 0;

            while(true)
            {
                number += _random.Next(100, 1000);

                if(number > 1000000)
                {
                    number = 0;
                }
            }
        }

        #endregion
        #region 프로그램 시작하기 - Main()

        /// <summary>
        /// 프로그램 시작하기
        /// </summary>
        private static void Main()
        {
            int processorCount = Environment.ProcessorCount;

            for(int i = 0; i < processorCount; i++)
            {
                Thread thread = new Thread(() => { ProcessThread(); });

                thread.Start();
            }
        }

        #endregion
    }
}

※ 윈도우즈 7에서는 작동하지 않는다.

728x90
반응형
Posted by 사용자 icodebroker
TAG , ,

댓글을 달아 주세요