static void MainThread(object state)
{
for (int i = 0; i < 5; i++)
Console.WriteLine("Hello Thread!");
}
Thread t = new Thread(MainThread);
MainThread는 쓰레드가 처음 실행할 함수를 지정한다. 이 외에도 매개변수를 전달해야 하는 경우 ParameterizedThreadStart
를 매개변수로 받을 수 있다.
t.Start();
설정한 기능을 수행하도록 쓰레드를 시작하는 함수
t.Join();
현재 실행 중인 쓰레드가 종료될 때까지 대기하는 함수
t.Sleep(int milliSecond);
현재 실행 중인 쓰레드가 종료될 때까지 대기하는 함수로 매개변수의 단위는 밀리세컨트(ms)이다.
함수들 외에도 쓰레드의 상태나 이름과 같은 속성을 가져오거나 설정할 수 있다.
어떤 쓰레드를 생성하고 실행할 함수를 지정해 실행시키는 것은 부담이 큰 작업이다. 간단한 일을 실행시키기 위해서 부담이 큰 쓰레드를 생성하는 상황을 위해 .NET에서는 ThreadPool
이라는 기능을 지원한다.
static void MainThread(object state)
{
for (int i = 0; i < 5; i++)
Console.WriteLine("Hello Thread!");
}
ThreadPool.QueueUserWorkItem(MainThread);
ThreadPool은 일종의 인력사무소라고 생각할 수 있는데 ThreadPool에 던져주는 Function을 대기하고 있는 Thread가 수행하는 방식이다.
ThreadPool에 많은 시간을 요구하는 작업들을 넘겨준다면 이후에 생기는 작업들은 오랜시간 동안 수행되지 못할 것이다. 그렇기 때문에, ThreadPool은 주로 짧은 작업을 처리하는데 사용된다.
ThreadPool에 존재하는 Thread의 개수를 MinThreads와 MaxThreads로 조절하는데 각각 getter와 setter를 지원한다. 쓰레드의 개수와 함께 completionPortThread
라는 정수형 매개변수를 추가로 받는데 I/O 완료 포트를 사용하는 쓰레드 수를 의미한다.
I/O 완료 포트라고 하니까 왠지 네트워크 관련 매개변수인것 같다. 아직은 잘 모르겠다.
I/O 완료 포트는, IOCP 서버에서 사용되는데 어떤 비동기 함수가 완료 되었을 때 실행될 콜백함수를 쓰레드 플에 있는 쓰레드 중 하나에 맡기는 구조를 의미한다. 즉 위의 설명에는 IOCP서버 구조에서 사용될 쓰레드 풀의 쓰레드 개수를 조정하는 것이다.
ThreadPool을 사용할 때 시간이 오래걸리는 작업을 실행하면 이후의 작업이 오랫동안 대기할 수도 있다. 이 문제를 해결하기 위해서 Task
를 사용할 수 있는데 ThreadPool에 직접 작업을 넘기는 것과 다르게 오래걸리는 작업이라는 것을 미리 알려줄 수 있다.
Task t = new Task(() => { while (true) { } }, TaskCreationOptions.LongRunning);
TaskCreationOptions
은 Task를 생성할 때 사용하는 옵션들로 위 상황같은 경우 오래 걸릴 것이라는 내용을 넣어 Task를 새로운 쓰레드에서 실행하도록 한다.
예를들어, ThreadPool에 5개의 Thread가 있는 상황에서 5개의 Task를 실행하고 ThreadPool에 새로운 일거리를 던져주는 상황이라 하자.
ThreadPool.SetMinThreads(1, 1);
ThreadPool.SetMaxThreads(5, 5);
for (int i = 0; i < 5; i++)
{
Task t = new Task(() => { while (true) { } });
t.Start();
}
ThreadPool.QueueUserWorkItem(MainThread);
위 상황에서 MainThread를 실행하지 않을 것이다. 하지만, Task를 생성할 때 LongRunning을 지정해 준다면 MainThread가 실행된다.
ThreadPool.SetMinThreads(1, 1);
ThreadPool.SetMaxThreads(5, 5);
for (int i = 0; i < 5; i++)
{
Task t = new Task(() => { while (true) { } }, TaskCreationOptions.LongRunning);
t.Start();
}
ThreadPool.QueueUserWorkItem(MainThread);
좋은 정보 감사합니다