방법: 스레드 풀 사용(C# 및 Visual Basic)

스레드 풀링은 작업이 큐에 추가된 다음 스레드가 만들어질 때 자동으로 시작되는 다중 스레딩의 한 형태입니다.자세한 내용은 스레드 풀링(C# 및 Visual Basic)을 참조하십시오.

다음 예제에서는 .NET Framework 스레드 풀을 사용하여 20과 40 사이의 숫자 10개에 대한 Fibonacci 결과를 계산합니다.각 Fibonacci 결과는 Fibonacci 클래스로 표현됩니다. 이 클래스는 계산을 수행하는 ThreadPoolCallback이라는 메서드를 제공합니다.각 Fibonacci 값을 나타내는 개체가 작성되고 ThreadPoolCallback 메서드가 QueueUserWorkItem에 전달되면 이 메서드를 실행하기 위해 풀의 사용 가능한 스레드가 할당됩니다.

각 Fibonacci 개체에는 계산을 위해 어느 정도 임의로 지정되는 값이 할당되고 각 스레드는 프로세서 시간을 할당 받기 위해 경쟁하므로 10개의 결과를 모두 계산하는 데 얼마나 오래 걸릴지 미리 알 수 없습니다.생성 과정에서 각 Fibonacci 개체가 ManualResetEvent 클래스의 인스턴스에 전달되는 이유는 바로 여기에 있습니다.각 개체는 해당 계산이 완료되면 제공된 이벤트 개체에 신호를 보내므로 10개의 Fibonacci 개체가 모두 결과를 계산할 때까지 기본 스레드에서 WaitAll을 사용한 실행을 차단할 수 있습니다.그런 다음 Main 메서드에서 각 Fibonacci 결과를 표시합니다.

예제

Imports System.Threading

Module Module1

    Public Class Fibonacci
        Private _n As Integer
        Private _fibOfN
        Private _doneEvent As ManualResetEvent

        Public ReadOnly Property N() As Integer
            Get
                Return _n
            End Get
        End Property

        Public ReadOnly Property FibOfN() As Integer
            Get
                Return _fibOfN
            End Get
        End Property

        Sub New(ByVal n As Integer, ByVal doneEvent As ManualResetEvent)
            _n = n
            _doneEvent = doneEvent
        End Sub

        ' Wrapper method for use with the thread pool.
        Public Sub ThreadPoolCallBack(ByVal threadContext As Object)
            Dim threadIndex As Integer = CType(threadContext, Integer)
            Console.WriteLine("thread {0} started...", threadIndex)
            _fibOfN = Calculate(_n)
            Console.WriteLine("thread {0} result calculated...", threadIndex)
            _doneEvent.Set()
        End Sub

        Public Function Calculate(ByVal n As Integer) As Integer
            If n <= 1 Then
                Return n
            End If
            Return Calculate(n - 1) + Calculate(n - 2)
        End Function

    End Class


    <MTAThread()> 
    Sub Main()
        Const FibonacciCalculations As Integer = 9 ' 0 to 9

        ' One event is used for each Fibonacci object
        Dim doneEvents(FibonacciCalculations) As ManualResetEvent
        Dim fibArray(FibonacciCalculations) As Fibonacci
        Dim r As New Random()

        ' Configure and start threads using ThreadPool.
        Console.WriteLine("launching {0} tasks...", FibonacciCalculations)

        For i As Integer = 0 To FibonacciCalculations
            doneEvents(i) = New ManualResetEvent(False)
            Dim f = New Fibonacci(r.Next(20, 40), doneEvents(i))
            fibArray(i) = f
            ThreadPool.QueueUserWorkItem(AddressOf f.ThreadPoolCallBack, i)
        Next

        ' Wait for all threads in pool to calculate.
        WaitHandle.WaitAll(doneEvents)
        Console.WriteLine("All calculations are complete.")

        ' Display the results.
        For i As Integer = 0 To FibonacciCalculations
            Dim f As Fibonacci = fibArray(i)
            Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN)
        Next
    End Sub

End Module
using System;
using System.Threading;

public class Fibonacci
{
    private int _n;
    private int _fibOfN;
    private ManualResetEvent _doneEvent;

    public int N { get { return _n; } }
    public int FibOfN { get { return _fibOfN; } }

    // Constructor.
    public Fibonacci(int n, ManualResetEvent doneEvent)
    {
        _n = n;
        _doneEvent = doneEvent;
    }

    // Wrapper method for use with thread pool.
    public void ThreadPoolCallback(Object threadContext)
    {
        int threadIndex = (int)threadContext;
        Console.WriteLine("thread {0} started...", threadIndex);
        _fibOfN = Calculate(_n);
        Console.WriteLine("thread {0} result calculated...", threadIndex);
        _doneEvent.Set();
    }

    // Recursive method that calculates the Nth Fibonacci number.
    public int Calculate(int n)
    {
        if (n <= 1)
        {
            return n;
        }

        return Calculate(n - 1) + Calculate(n - 2);
    }
}

public class ThreadPoolExample
{
    static void Main()
    {
        const int FibonacciCalculations = 10;

        // One event is used for each Fibonacci object.
        ManualResetEvent[] doneEvents = new ManualResetEvent[FibonacciCalculations];
        Fibonacci[] fibArray = new Fibonacci[FibonacciCalculations];
        Random r = new Random();

        // Configure and start threads using ThreadPool.
        Console.WriteLine("launching {0} tasks...", FibonacciCalculations);
        for (int i = 0; i < FibonacciCalculations; i++)
        {
            doneEvents[i] = new ManualResetEvent(false);
            Fibonacci f = new Fibonacci(r.Next(20, 40), doneEvents[i]);
            fibArray[i] = f;
            ThreadPool.QueueUserWorkItem(f.ThreadPoolCallback, i);
        }

        // Wait for all threads in pool to calculate.
        WaitHandle.WaitAll(doneEvents);
        Console.WriteLine("All calculations are complete.");

        // Display the results.
        for (int i= 0; i<FibonacciCalculations; i++)
        {
            Fibonacci f = fibArray[i];
            Console.WriteLine("Fibonacci({0}) = {1}", f.N, f.FibOfN);
        }
    }
}

다음은 출력의 예입니다.

launching 10 tasks...
thread 0 started...
thread 1 started...
thread 1 result calculated...
thread 2 started...
thread 2 result calculated...
thread 3 started...
thread 3 result calculated...
thread 4 started...
thread 0 result calculated...
thread 5 started...
thread 5 result calculated...
thread 6 started...
thread 4 result calculated...
thread 7 started...
thread 6 result calculated...
thread 8 started...
thread 8 result calculated...
thread 9 started...
thread 9 result calculated...
thread 7 result calculated...
All calculations are complete.
Fibonacci(38) = 39088169
Fibonacci(29) = 514229
Fibonacci(25) = 75025
Fibonacci(22) = 17711
Fibonacci(38) = 39088169
Fibonacci(29) = 514229
Fibonacci(29) = 514229
Fibonacci(38) = 39088169
Fibonacci(21) = 10946
Fibonacci(27) = 196418

참고 항목

참조

Mutex

WaitAll

ManualResetEvent

Set

ThreadPool

QueueUserWorkItem

ManualResetEvent

개념

스레드 풀링(C# 및 Visual Basic)

Monitor

기타 리소스

스레딩(C# 및 Visual Basic)

HOWTO: Visual C# .NET을 사용하여 다중 스레딩 환경에서 공유 리소스에 대한 액세스 동기화

.NET Framework의 보안