C# Rookiss Part4 게임서버 : Thread생성
🙇♀️Thread
- thread는 일꾼!
- cpu가 영혼을 넣어주면 작동!
- 기본적으로foreground이다
- backgound면 메인함수가 끝나면 자동적으로 쓰레드가 종료
- thread들이 동시 실행가능한 수는 cpu 코어 개수와 같다
🪐Thread
class Program
{
static void MainThread()
{
while(true)
Console.WriteLine("Hello Thread!");
}
static void Main(string[] args)
{
Thread t = new Thread(MainThread); // thread의 메인 함수를 설정해 주어야 됨 (t가 할일!)
t.IsBackground = true; // t를 background로 설정
t.Start(); // t가 일을 시작
Console.WriteLine("Hello World!");
}
}
- 쓰레드의 메인함수를 만들기
- 쓰레드를 생성시 메인함수를 인자로 넣어주어야 함
- start함수로 일을 시작
- 기본적으로 IsBackground = false 상태
🪐Join
Thread t = new Thread(MainThread);
t.Name = "Test Thread";
t.IsBackground = true;
t.Start();
Console.WriteLine("Waiting for Thread!");
t.Join();
Console.WriteLine("Hello World!");
위에 결과는 Hello Thread!가 무한 반복된다 (Waiting for Thread! 출력 x)
- Join 함수
- 쓰레드의 일이 끝날 때 까지 기다린 후 다음 줄 실행
t.Start();
가 끝난 뒤Console.WriteLine("Hello World!");
가 실행됨
Join이 없으면 메인함수가 우선!
🪐ThreadPool
쓰레드풀은 직원을 이미 몇명두고 단기알바를 할 인력을 투입한다 투입한 인력이 일을 마치고 오면 그제서야 다시 인력을 투입한다 짧은 일감을 준다면 효율이 좋지만 그렇지않다면 일꾼이 부족해져서 먹통이 될수있다
- ThreadPool로 구한 인력은 기본적으로 Background로 돌아간다!
- 쓰레드풀로 단기 알바구하기!
ThreadPool.QueueUserWorkItem(MainThread);
static void MainThread(Object state) { }
처럼 Object를 인자로 받아야 됨
- 쓰레드풀은 가벼운 일을 시키는 것이 좋다!
ThreadPool.SetMinThreads(1, 1);
ThreadPool.SetMaxThreads(5, 5);
for (int i = 0; i < 5; i++)
ThreadPool.QueueUserWorkItem((obj) => { while (true) { } });
ThreadPool.QueueUserWorkItem(MainThread);
이렇게 된다면 일꾼 다섯명이 (obj) => { while (true) { } }
부분에서 나오질 못하고, 그 뒤 ThreadPool.QueueUserWorkItem(MainThread);
을 실행할 일꾼이 없어진다
일꾼이 없으므로 프로그램이 먹통이 됨!
🪐Task
- 직원을 고용한다기 보다는 직원이 할 일을 정의해서 사용하겠다는 뜻
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);
- Task는 Action대리자를 인자로 받음
- 두번째 인자로 TaskCreationOptions.LongRunning는 함수가 오래걸린다는것을 알림
- 쓰레드 풀에서 인력을 얻는것이 아니라 별도 처리가 됨
- 보통 쓰레드풀이나 테스크를 사용 (쓰레드를 직접 생성하는 일은 드물다)