C# - 다중 스레드: 초보자 가이드

안녕하세요, 미래의 C# 개발자 여러분! 오늘 우리는 다중 스레딩의 세계로 흥미로운 여정을 떠납니다. 이 용어가 두려울 것 같다면 걱정 마세요 - 나는 여러분의 친절한 안내자가 되겠습니다. 단계별로 차근차근 설명하겠습니다. 이 튜토리얼의 끝을 맺을 때까지, 여러분은 프로처럼 스레딩을 할 수 있을 것입니다!

C# - Multithreading

다중 스레딩이란?

먼저 다중 스레딩이 무엇인지 이해해 보겠습니다. 복잡한 식사를 요리하는 상상해 봅시다. 하나씩 작업을 할 것 같나요? 아니면 한쪽 냄비에 파스타를 끓이면서 다른 쪽에서 채소를 썰고 소스를 주의 깊게 지켜볼까요? 이것이 멀티태스킹이고, 프로그래밍의 세계에서는 이를 다중 스레딩이라고 부릅니다.

다중 스레딩은 프로그램이 동시에 여러 작업을 수행할 수 있게 합니다. 여러 명의 요리사가 주방에서 각기 다른 부분의 식사를 담당하는 것과 같습니다.

스레드 생명 주기

우리와 마찬가지로 스레드는 생명 주기를 가지고 있습니다. 생명 주기를 간단히 설명해 보겠습니다:

  1. 태어남 (New): 스레드가 생성되었지만 아직 시작되지 않았습니다.
  2. 준비됨 (Ready): 스레드는 실행할 준비가 되었고 CPU 시간을 기다리고 있습니다.
  3. 실행 중 (Running): 스레드는 작업을 실행하고 있습니다.
  4. 차단됨 (Blocked): 스레드는 일시적으로 중지되었습니다 (아마 어떤 자원을 기다리는 중일 것입니다).
  5. 죽음 (Dead): 스레드는 작업을 완료했고 더 이상 실행되지 않습니다.

다음은 간단한 시각화입니다:

New -> Ready -> Running -> Dead
^        |
|        v
<-- Blocked

메인 스레드

C# 프로그램을 시작할 때, 자동으로 메인 스레드라는 스레드를 생성합니다. 우리의 주방 비유에서는 주채프입니다. 메인 스레드를 어떻게 사용하는지 보겠습니다:

using System;
using System.Threading;

class Program
{
static void Main(string[] args)
{
Console.WriteLine("메인 스레드: " + Thread.CurrentThread.ManagedThreadId);
}
}

이를 실행하면 다음과 같은 결과를 볼 수 있습니다:

메인 스레드: 1

이는 우리의 프로그램이 메인 스레드에서 실행되고 있으며, 메인 스레드의 ID는 항상 1이라는 것을 보여줍니다.

Thread 클래스의 속성과 메서드

C#의 Thread 클래스는 유용한 속성과 메서드를 많이 제공합니다. 가장 일반적인 몇 가지를 살펴보겠습니다:

속성/메서드 설명
ManagedThreadId 스레드의 고유 식별자를 가져옵니다
IsAlive 이 스레드가 시작되었고 아직 종료되지 않았는지 나타냅니다
Name 스레드의 이름을 가져오거나 설정합니다
Priority 스레드의 예약 우선순위를 가져오거나 설정합니다
Start() 스레드를 시작합니다
Sleep() 스레드를 지정된 시간 동안 중지합니다
Join() 호출하는 스레드가 이 스레드가 종료할 때까지 기다입니다

다음은 몇 가지 속성과 메서드를 사용하는 예제입니다:

using System;
using System.Threading;

class Program
{
static void Main(string[] args)
{
Thread t = new Thread(DoWork);
t.Name = "Worker Thread";
Console.WriteLine("스레드 시작...");
t.Start();
t.Join();
Console.WriteLine("스레드 완료");
}

static void DoWork()
{
Console.WriteLine($"스레드 {Thread.CurrentThread.Name} 작업 중");
Thread.Sleep(1000);
Console.WriteLine($"스레드 {Thread.CurrentThread.Name} 작업 완료");
}
}

이 프로그램은 새로운 스레드를 생성하고 이름을 지정한 후 시작하고, 스레드가 완료될 때까지 기다렸다가 계속합니다. 출력은 다음과 같습니다:

스레드 시작...
스레드 Worker Thread 작업 중
스레드 Worker Thread 작업 완료
스레드 완료

스레드 생성

C#에서 스레드를 생성하는 것은 주방에 새 요리사를 고용하는 것과 같습니다. 다음은 스레드를 생성하는 방법입니다:

using System;
using System.Threading;

class Program
{
static void Main(string[] args)
{
// 메서드 이름을 사용하여 스레드 생성
Thread t1 = new Thread(DoWork);
t1.Start();

// 익명 메서드를 사용하여 스레드 생성
Thread t2 = new Thread(() =>
{
Console.WriteLine("스레드 2 작업 중");
});
t2.Start();

// 매개변수를 사용하여 스레드 생성
Thread t3 = new Thread(param =>
{
Console.WriteLine($"스레드 3: {param}");
});
t3.Start("스레드 3에서 온 인사!");
}

static void DoWork()
{
Console.WriteLine("스레드 1 작업 중");
}
}

이 예제는 스레드를 생성하는 세 가지 다른 방법을 보여줍니다. 실행하고 결과를 확인해 보세요!

스레드 관리

스레드 관리는 효율적인 다중 스레딩에 매우 중요합니다. 다음은 스레드를 관리하는 몇 가지 방법입니다:

using System;
using System.Threading;

class Program
{
static void Main(string[] args)
{
Thread t = new Thread(DoWork);
t.Start();

// 스레드가 완료될 때까지 기다림
t.Join();

// 스레드 우선순위 설정
t.Priority = ThreadPriority.Highest;

// 스레드 상태 확인
Console.WriteLine($"스레드가 살아있나요? {t.IsAlive}");

// 메인 스레드를 일시 중지
Thread.Sleep(1000);
}

static void DoWork()
{
for (int i = 0; i < 5; i++)
{
Console.WriteLine($"작업 중... {i}");
Thread.Sleep(500);
}
}
}

이 예제는 스레드가 완료될 때까지 기다리는 방법, 스레드 우선순위 설정, 스레드 상태 확인, 메인 스레드를 일시 중지하는 방법을 보여줍니다.

스레드 파괴

C#에서는 일반적으로 스레드를 수동으로 파괴하지 않습니다. 스레드는 작업을 완료하거나 애플리케이션이 종료될 때 자동으로 종료됩니다. 그러나 Abort() 메서드를 사용하여 스레드를 중지할 수 있습니다. 그러나 자원 정리 문제로 인해 일반적으로 권장되지 않습니다.

다음은 Abort() 메서드를 사용하는 예제입니다. 하지만 이 방법은 자원 정리에 주의해야 합니다:

using System;
using System.Threading;

class Program
{
static void Main(string[] args)
{
Thread t = new Thread(DoWork);
t.Start();

Thread.Sleep(2000); // 스레드가 2초 동안 실행하도록 허용

t.Abort(); // 스레드 중지
Console.WriteLine("스레드 중지");
}

static void DoWork()
{
while (true)
{
Console.WriteLine("작업 중...");
Thread.Sleep(500);
}
}
}

이 프로그램은 스레드를 2초 동안 실행한 후 중지합니다.

이제 여러분은 C# 다중 스레딩의 첫 번째 강의를 마친 것입니다. 요리를 배우는 것처럼, 다중 스레딩을 마스터하려면 연습이 필요합니다. 이 개념들을 실험해 보지 마세요! 행복한 코딩을 기원하며, 여러분의 스레드가 항상 원활하게 실행되길 바랍니다!

Credits: Image by storyset