C#/C# 교과서

[C# 교과서] 55. 스레드

서니션 2023. 2. 8. 10:41
728x90
반응형

닷넷에서 스레드는 작업자 한 명을 나타냄

다중 스레드 또는 다중 스레딩은 여러 작업자를 두고 동시에 여러 작업을 처리하는 것을 의미


스레드

C#의 메인 메서드 코드는 순차적으로 실행 됨

하지만 메인 메서드에 또 다른 메서드 단위로 프로그램을 작성하고, 이를 스레드 개체로 실행하면 메서드의 실행 순서를 윈도 운영 체제에 맡길 수 있음

그러면 순차적으로 실행되지 않고 반복적으로 여러 메서드를 나누어서 처리 가능

스레드는 이처럼 순차적으로 처리되지 않고, 여러 기능을 동시 다발적으로 실행할 때 사용하는 개념이며, 이를 닷넷에서는 Thread같은 클래스로 제공

 

  • 프로세스 : 현재 실행 중인 프로그램
  • 스레드 : 운영 체제가 프로세서 시간을 할당하는 기본 단위

스레드는 작업자 한 명

스레드를 현실 세계에 비유하면 '작업자 한 명' 을 의미

여러 스레드를 이용하여 일을 진행하는 방식을 병렬(parallel) 프로그래밍이라고 함

 

C#에서 스레드를 만들 때는 System.Threading 네임스페이스에 정의된 ThreadStart 대리자를 사용해야함

public delegate void ThreadStart();

 

ThreadStart 대리자로 스레드를 선언할 수도 있음

스레드는 스레드에 담을 메서드를 여러개 구현해 놓고 이를 Thread 대리자에 등록하면 됨

ThreadStart 대리자 개체를 Thread 클래스의 생성자로 받은 후 Thread 개체와 Start() 메서드를 호출하여 스레드에 담긴 메서드를 호출하는 형태

> using System.Threading;
> public static void Hi() { Console.WriteLine("Hi"); }
> Thread t = new Thread(new System.Threading.ThreadStart(Hi));
> t.Start();
Hi

Thread 클래스의 주요 멤버

  • Priority : 스레드의 우선순위를 결정. ThreadPriority 열거형의 Highest, Normal, Lowest 값을 찾음
  • Abort() : 스레드를 종료시킴
  • Sleep() : 스레드를 설정된 밀리초(1000분의 1초)만큼 중지시킴
  • Start() : 스레드를 시작

스레드 생성 및 호출하기

using System;
using System.Threading;

class ThreadDemo
{
    static void Other()
    {
        Console.WriteLine("[?] 다른 작업자 일 실행");
        Thread.Sleep(1000); // 1초 대기(지연)
        Console.WriteLine("[?] 다른 작업자 일 종료");
    }

    static void Main()
    {
        Console.WriteLine("[1] 메인 작업자 일 시작");

        // Thread 클래스와 ThreadStart 대리자로 새로운 스레드 생성
        var other = new Thread(new ThreadStart(Other));
        other.Start(); // 새로운 스레드 실행

        Console.WriteLine("[2] 메인 작업자 일 종료");
    }
}

메인 작업자 스레드는 일을 시작하자마자 바로 실행되어 먼저 메시지를 출력하지만,

다른 작업자 스레드는 생성한 후 1초간 지연되어 나중에 Other() 메서드 내용을 출력함


다중 스레드를 사용한 메서드 함께 호출하기

메서드 3개를 서로 다른 스레드 3개에 할당하여 실행하는 프로그램

using System;
using System.Diagnostics;
using System.Threading;

class ThreadPractice
{
    private static void Ide()
    {
        Thread.Sleep(3000); // 3초 딜레이
        Console.WriteLine("[3] IDE : VS Code");
    }

    private static void Sql()
    {
        Thread.Sleep(3000);
        Console.WriteLine("[2] DBMS : SQL Server");
    }

    private static void Win()
    {
        Thread.Sleep(3000);
        Console.WriteLine("[1] OS : Windows Server");
    }

    static void Main()
    {
        // 스레드
        ThreadStart ts1 = new ThreadStart(Win);
        ThreadStart ts2 = new ThreadStart(Sql);

        Thread t1 = new Thread(ts1);
        var t2 = new Thread(ts2);
        var t3 = new Thread(new ThreadStart(Ide))
        {
            Priority = ThreadPriority.Highest // 우선순위 높게
        };

        t1.Start();
        t2.Start();
        t3.Start();

        // 프로세스
        //Process.Start("IExplore.exe"); // 익스플로러 실행
        Process.Start("Notepad.exe"); // 메모장 실행
    }
}

익스플로러랑 메모장 실행되는 것 까지 확인 가능

결과는 매번 다르게 표현될 수 있음!


스레드 동기화

여러 스레드를 동시에 실행할 때 발생하는 문제는 한 스레드가 메서드를 실행하는 동안 다른 스레드도 같은 메서드를 실행하려고 해서 오류가 발생

 

이를 해결하려고 다른 스레드가 액세스하지 못하도록 스레드를 잠굴 수 있음 -> 스레드 동기화

lock (this)
{
	// 스레드 동기화가 필요한 코드 블록
}

 

728x90
반응형