본문 바로가기
cs공부/운영체제

C# - 운영체제 쓰레드 코드(ThreadPool, Task 등)

by 코딩하는 돼징 2023. 4. 27.
반응형

운영체제 쓰레드 관련 이론 알아보러 가기

 

운영체제 - 쓰레드(Thread), 기아상태,쓰레드풀(Thread Pool)

쓰레드(Thread) 음식점 - 프로세스 직원 - 쓰레드 영혼 - CPU(코어) 01 전통적 프로세스(heavy weight process) 프로세스 간의 공유 변수를 갖기 어렵다. 운영체제가 제공하는 특수 구조체나 공유파일을 사

code-piggy.tistory.com


1. 쓰레드 만들기

01 ThreadStart대리자 혹은 ParameterizedThreadStart

public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(object? obj);

02 쓰레드가 시작될때 개체가 대리자를 지정하여 새 인스턴스를 초기화한다.

public Thread (System.Threading.ThreadStart start);
public Thread (System.Threading.ParameterizedThreadStart start, int maxStackSize);

03 Thread.Start

public void Start ();

04 ThreadId가져오기

public int ManagedThreadId { get; }

04 Code예시

매개 변수가 없는 경우

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); // 기본적으로 foreground로 실행된다
            // background로 실행을 원할 시
            t.IsBackground = true;
            t.Start();

            Console.WriteLine("Hello World");
        }
    }
}

MainThread는 ThreadStart delegate 요구 사항에 따라 매개 변수가 없고 반환값도 없는 메서드 이다. 따라서 Thread 클래스의 생성자는 MainThread 메서드를 쓰레드로 실행할 수 있도록 하는 인자로 받을 수 있다.

ThreadStart threadStart = new ThreadStart(MainThread);
Thread t = new Thread(threadStart);
t.Start();

01 forground 일시

02 background 일시


매개 변수가 없는 경우

using System;
using System.Threading;

namespace ServerCore
{
    class Program
    {
        static void MainThread(object id)
        {
            Console.WriteLine($"내 id는 {id}");
        }
        static void Main(string[] args)
        {
            int id = 5;
            ParameterizedThreadStart threadStart = new ParameterizedThreadStart(MainThread);
            Thread t = new Thread(threadStart);
            t.Start(id);

            Console.WriteLine("Hello World");
        }
    }
}

람다식을 사용할 경우 이렇게 작성할 수도 있다.

Thread t = new Thread(()=> MainThread(id));
t.Start(id);

3. ThreadPool(직원들의 대기 집합)

단기 알바 고용하는 경우

쓰레드 하나를 추가할때마다 많은 부담이 생긴다(ex) 식당에 정직원을 한명씩 더 고용하는 듯한 느낌)

만약 인력사무소에서 10명의 직원이 있어서 일을하러가면 일을 끝내고 돌아오기 전까지 일을 더 할 수 없다. 일을 하고 돌아온 후 일감을 기다리는 상태에서 일을 다시 시작할 수 있다.

static void MainThread(object state)
{
	for (int i = 0; i < 5; i++)
	{
		Console.WriteLine("Hello Thread");
	}
}
static void Main(string[] args)
{
	// 단기 알바 일감 건네주기
    // background로 돌아간다
	ThreadPool.QueueUserWorkItem(MainThread);
    
    while(true)
    {

    }
}


01 SetMinThreads

public static bool SetMinThreads (int workerThreads, int completionPortThreads);

파라미터

workerThreads : 최소 직원 수

completionPortThreads : 최소 asynchronous I/O threads 수 

ThreadPool.SetMinThreads(1, 1); // 첫번째 인자가 QueueUserWorkItem을 실행하는 최소 일꾼이다.
ThreadPool.QueueUserWorkItem(MainThread);

02 SetMaxThreads

public static bool SetMaxThreads (int workerThreads, int completionPortThreads);

파라미터

workerThreads : 최대 직원 수

completionPortThreads : 최대 asynchronous I/O threads 수

ThreadPool.SetMaxThreads(5, 5);
ThreadPool.QueueUserWorkItem(MainThread);

ThreadPool.SetMinThreads(1, 1);
ThreadPool.SetMaxThreads(5, 5);
ThreadPool.QueueUserWorkItem(MainThread);

최소1개 최대 5개 만약 5명의 일꾼들이 다 나가있으면 일감이 들어와도 일을 하러가지 못한다.

 

for (int i = 0; i < 5; i++)
{
	// 오브젝트를 받아서 무엇무엇인가(while문 무한루프 => 영영 돌아올 수 없는 일감)를 하는 것을 만들어주세요
	ThreadPool.QueueUserWorkItem((obj) => { while (true) { } } ); // 람다 사용
}

ThreadPool.QueueUserWorkItem(MainThread);

일꾼들이 영영 돌아올 수 없는 일감을 하러가서 밑에 일을하러가지 못한다.

 

만약 최대 일꾼을 사용하지 않고 4명만 사용한 경우

for (int i = 0; i < 4; i++)
{
	// 오브젝트를 받아서 무엇무엇인가(while문 무한루프 => 영영 돌아올 수 없는 일감)를 하는 것을 만들어주세요
	ThreadPool.QueueUserWorkItem((obj) => { while (true) { } } ); // 람다 사용
}

ThreadPool.QueueUserWorkItem(MainThread);

while(true){ }


4. Task

Task클래스는 .NET에서 제공하는 TPL(Task Parallel Library)의 일부로서 비동기 작업을 효과적으로 처리하는데 사용된다. 여러 작업을 병렬적으로 실행하고 관리할 수 있다.

using System.Threading.Tasks;

static void Main(string[] args)
{
	Task t = new Task(() => { while (true) { } });
	t.Start();
}

01 TaskCreationOptions.LongRunning

LongRunning으로 설정시 새로운 ThreadPool과는 별도의 쓰레드를 생성하면서 처리 하게 된다.

Task t = new Task(() => { while (true) { } }, TaskCreationOptions.LongRunning);

5명의 일꾼들이 다 일을 하러 갔는데 일처리가 진행됐음을 확인할 수 있다.

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);

while(true)
{ }

 

 

참고 :  본 내용은 MMORPG  PART4 강의를 수강하여 작성하였습니다.

https://www.inflearn.com/course/%EC%9C%A0%EB%8B%88%ED%8B%B0-mmorpg-%EA%B0%9C%EB%B0%9C-part4

반응형

댓글