>  기사  >  백엔드 개발  >  C#은 스레드 풀 기능을 자체적으로 구현합니다. (2)

C#은 스레드 풀 기능을 자체적으로 구현합니다. (2)

黄舟
黄舟원래의
2016-12-27 14:37:351517검색

소개

이전 글에서 C#은 스스로 스레드 풀 기능을 구현한다(1). 기본적으로는 실행할 수 있는 프로그램을 구현했지만 실제로 스레드 풀이라고 할 수는 없다. 이전 글의 코드에는 치명적인 버그가 있기 때문에, 즉 태스크가 없으면 기다리지 않고, 대신 미친듯이 while 루프를 돌면서 태스크 목록을 잠그려고 하는 것입니다. 성능이 상당히 낮고 프로그램 응답 속도가 매우 느린 이유는 방금 언급한 것과 같습니다.

이 문제를 해결하려면 프로그램이 프로세스를 동기화할 수 있도록 하는 몇 가지 방법을 사용해야 합니다.

방법 1

세마포어 사용

태스크의 잠금 연산을 줄이기 위해 태스크가 비어 있지 않을 때만 테스트를 수행합니다. 세마포어는 작업 테이블의 숫자를 나타냅니다. s.WaitOne(); 작업을 잠그고 제거하기 시작합니다

while (flag && TaskQueue != null)
            {
                //等待任务
                ThreadPoolManager.s.WaitOne();
                //获取任务
                lock (TaskQueue)
                {
                    try
                    {
                        if (TaskQueue.Count > 0)
                            task = TaskQueue.Dequeue();
                        else
                            task = null;
                    }
                    catch (Exception)
                    {
                        task = null;
                    }
                    if (task == null)
                        continue;

ThreadPoolManager 클래스에 두 개의 변수 추가

//由于采用信号量需要定义一个
        public int MaxJobNum = 1000;
        public static Semaphore s;


세마포어 초기화 s = new Semaphore(0, MaxJobNum);


이런 방식으로 동기화 달성할 수 있습니다

아래 테스트 클래스가 제공됩니다

static void Main(string[] args)
       {
           ThreadPoolManager tpm = new ThreadPoolManager(2);
 
           TestTask t1 = new TestTask("task1");
           TestTask t2 = new TestTask("task2");
           TestTask t3 = new TestTask("task3");
           TestTask t4 = new TestTask("task4");
           TestTask t5 = new TestTask("task5");
           TestTask t6 = new TestTask("task6");
           TestTask t7 = new TestTask("task7");
           TestTask t8 = new TestTask("task8");
           TestTask t9 = new TestTask("task9");
 
           tpm.AddTask(t1);
           tpm.AddTask(t2);
           tpm.AddTask(t3);
           tpm.AddTask(t4);
           tpm.AddTask(t5);
           tpm.AddTask(t6);
           tpm.AddTask(t7);
           tpm.AddTask(t8);
           tpm.AddTask(t9);
       }


201ac8a5914f21ff228299a472e1fbfbvcD4KPGgxPre9t6i2/jwvaDE+Cs7Sw8eyu8rH08PQxbrFwb+jrM7Sw8fKudPDQXV0b1Jlc2V0RXZlbnTAtMq1z9bNrLK9Cjxicj4KCrXa0ruyvaOs1NpUaHJ lYWRQb 29sTWFuYWdlcrP1yry7r8qxuvK0tL2o0ru49iAgbG9ja3MgPSBuZXcgQXV0b1Jlc2V 0RXZlbnQoZmFsc2UpOwq1sUFkZFRhc2u1xMqxuvJsb2Nrcy5TZXQoKTvNqNqNaqtci0/bXEstnX 96GjCsi7uvPO0sPHttRXb3JrVGhyZWFktcRydW66r8r91/bSu7j20KHQobXE0N64xAo8cHJlIGNsYXNzPQ=="brush:java;"> public void run() { while (플래그 && TaskQueue != null ) { //작업 대기 중//ThreadPoolManager.sep.WaitOne(); //작업 대기 중 while (TaskQueue.Count == 0 && flag) { try { ThreadPoolManager.locks.WaitOne() } catch(예외) { } } //작업 잠금 가져오기(TaskQueue) { try { task = TaskQueue.Dequeue(); } catch(예외) { task = null; } if(task == null) continue; task .StartTask(); } catch(예외) { } try { if (!task.IsEnd()) { task.SetEnd(false); } } catch(예외); of while }작업 목록 개수가 0인 경우에만 AddTask까지 차단하고 계속 진행합니다

위는 C# 자체 스레드 풀 기능 구현 내용입니다(2). PHP 중국어 넷(www.php.cn)에 주목하세요!



성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.