Home 5강 쓰레드 생성
Post
Cancel

5강 쓰레드 생성

5강 쓰레드 생성

ServerCore 파일의 Program.cs (중요) 에서

다음 코딩

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Threading;

namespace ServerCore
{
    class Program
    {
        static void MainThread()
        {
            Console.WriteLine("Hello Thread!");
        }

        static void Main(string[] args)
        {
            Thread t = new Thread(MainThread); //MainThread 스레드 생성 (서브 직원)
            t.Start(); //일을 하라고 명령. (스레드 실행)

            Console.WriteLine("Hello Main!");
        }
    }
}

C#의 스레드는 기본적으로 앞에서 실행되게 만들어진다 (폴 그라운드) ↔ 백그라운드

1
t.IsBackground = true;

백그라운드 실행

1
2
3
4
5
6
7
8
9
10
11
12
13
14
static void MainThread()
        {
            while(true)
            Console.WriteLine("Hello Thread!");
        }

static void Main(string[] args)
        {
            Thread t = new Thread(MainThread); //MainThread 스레드 생성 (서브 직원)
            t.IsBackground = true;
            t.Start(); //일을 하라고 명령. (스레드 실행)

            Console.WriteLine("Hello Main!");
        }
  • 다음과 같다면 백그라운드 실행 스레드는 폴그라운드 실행 스레드가 끝나면 자동 종료

백그라운드 실행 종료 대기하기

1
2
Console.WriteLine("Waiting for Thread!");
t.Join();

스레드 이름 설정

1
t.Name = "Test Background Thread";

다음과 같이 확인 가능

Untitled )

스레드풀링 (단기알바 고용)

1
2
3
4
5
6
7
8
9
10
11
12
13
static void MainThread(object state)
        {
            for(int i=0; i<5; i++)
            Console.WriteLine("Hello Thread!");
        }

static void Main(string[] args)
        {
            ThreadPool.QueueUserWorkItem(MainThread);//단기알바 모집
            //백그라운드로 돌아가는 스레드

            while (true) { }
        }
  • 결과: 스레드 업무를 다 실행한 다음 종료되지 않고 지속

Untitled

원리

이미 스레드들이 마련되어있음 (직원 고용이 완료) ⇒ 스레드 대기소에서 대기중인 상태

스레드의 할일 실행 ⇒ 스레드의 할일이 끝나면, 다시 스레드 대기소 들어가서 대기함

주의 점

기존에 있던 풀에서 활용을 하는 것이므로, 풀에 비해서 일감이 많을 시

먹통이 될 수가 있다 (예- 무한루프 일감)

= 기존 인력이 돌아오지 않는 경우

cf) 오브젝트 풀링

오브젝트를 풀에 대기시켰다가 필요할때가 되면 재사용함

이와 같은 원리임

스레드가 너~무 많을 시

1
2
3
4
5
6
for (int i = 0; i < 1000; i++) {
                Thread t = new Thread(MainThread); //MainThread 스레드 생성 (서브 직원)
                //t.Name = "Test Background Thread";
                t.IsBackground = true;
                t.Start(); //일을 하라고 명령. (스레드 실행)
            }
  • 1000개의 스레드를 만들어서 일을 시키는 중

어떨까?

스레드를 생성해서 일을 시키는 일이

스레드가 실제로 해야 할 일을 하는 것보다 오랜 시간이 걸릴 것 ⇒ 🤮최악!

영영 돌아오지 않는 스레드

일감 (hello thread 5번 출력)

1
2
3
4
5
static void MainThread(object state)
        {
            for(int i=0; i<5; i++)
            Console.WriteLine("Hello Thread!");
        }

스레드 인력 사무소

1
2
3
4
5
6
7
8
9
10
11
12
static void Main(string[] args)
        {
            ThreadPool.SetMinThreads(1, 1); //최소 스레드 1개
            ThreadPool.SetMaxThreads(5, 5); //최대 스레그 5개 설정

            for (int i = 0; i < 5; i++) {
                //obj를 받아서 무한루프를 실행하도록 해줌
                ThreadPool.QueueUserWorkItem((obj)=> { while (true) { } });
            }
            ThreadPool.QueueUserWorkItem(MainThread);//단기알바 모집
            //일감 (hello thread 5번 출력)
				}

해석

1
2
3
4
for (int i = 0; i < 5; i++) {
                //obj를 받아서 무한루프를 실행하도록 해줌
                ThreadPool.QueueUserWorkItem((obj)=> { while (true) { } });
            }

스레드가 5개가 존재함.

이 부분에서 5개의 스레드가 무한 루프를 돌고있어 남는 스레드가 없으므로 일감을 수행할 스레드가 없어서 먹통이 된다

Task ⇒ 스레드의 먹통 단점 극복

결과: 먹통이 되는 일감이 있어도, MainThread 일들을 일단 처리하게 될 것

1
2
3
4
Task t = new Task(() => { while (true) { } }, TaskCreationOptions.LongRunning);
            //오래 걸리는 작업임을 알려줌

t.Start();

Task

직원이 할 일감 단위를 정해줌

스레드 풀에 넣어져서 관리하게 활용할 것

옵션 설명

🔥

TaskCreationOptions.LongRunning : 오래 걸리는 일감임을 알려줌

  • 이 기능으로 먹통이 될 일이 없게 된다 (이 옵션이 없다면 다시 먹통이 됨)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
static void MainThread(object state)
{
            for(int i=0; i<5; i++)
            Console.WriteLine("Hello Thread!");
}
static void Main(string[] args)
{
	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();
   }
}

* 람다 식*

같은 의미이다

1
2
3
4
5
6
7
8
9
static void MainThread(object state)
{
	while(true) {}
}

static void Main(string[] args)
{
	ThreadPool.QueueUserWorkItem(MainThread);//단기알바 모집
}

object 형식으로 state를 인자로 받는 것

== (obj)=> { while (true) { } }

1
2
3
static void Main(string[] args){
	ThreadPool.QueueUserWorkItem((obj)=> { while (true) { } });
}

인자가 없는 람다 식

() => { while (true) { } })

This post is licensed under CC BY 4.0 by the author.