반응형
C# 태스크 병렬 라이브러리(TPL) - 태스크 생성
**태스크 병렬 라이브러리(TPL)**은 멀티스레드 프로그래밍을 쉽게 하기 위해 .NET에서 제공하는 기능입니다. Task는 TPL의 핵심 클래스 중 하나로, 비동기 작업을 처리하고 스레드 풀(Thread Pool)을 활용하여 작업을 병렬로 실행합니다.
예제 코드 분석
internal class Program
{
static void TaskMethod(string name)
{
Console.WriteLine("Task {0} is running on thread id {1}. Is thread pool thread : {2}",
name,
Thread.CurrentThread.ManagedThreadId,
Thread.CurrentThread.IsThreadPoolThread);
}
static void Main(string[] args)
{
var t1 = new Task(() => TaskMethod("Task 1"));
var t2 = new Task(() => TaskMethod("Task 2"));
t2.Start(); // Task 2 시작
t1.Start(); // Task 1 시작
Task.Run(() => TaskMethod("Task 3")); // Task 3 시작
Task.Factory.StartNew(() => TaskMethod("Task 4")); // Task 4 시작
Task.Factory.StartNew(() => TaskMethod("Task 5"), TaskCreationOptions.LongRunning); // Task 5 시작 (LongRunning 옵션)
Thread.Sleep(TimeSpan.FromSeconds(1)); // 메인 스레드 대기 (태스크 실행 기다림)
}
}
코드 동작 과정
- Task 생성
- 태스크 생성:
- t1과 t2는 Task 객체를 생성했지만, 아직 실행되지 않았습니다.
- 중요: 태스크를 생성한다고 해서 바로 실행되지 않습니다. .Start()를 호출해야 태스크가 실행됩니다.
-
var t1 = new Task(() => TaskMethod("Task 1")); var t2 = new Task(() => TaskMethod("Task 2"));
- 태스크 생성:
- 태스크 실행
- t2.Start()와 t1.Start()를 호출하면 태스크가 실행되고, 스레드 풀(Thread Pool)에서 스레드를 가져와 작업을 수행합니다.
- 태스크 실행 순서는 t2가 먼저 호출되었지만, 실제 실행 순서는 스레드 스케줄러에 의해 결정되므로 순서가 보장되지 않습니다.
-
t2.Start(); t1.Start();
- Task.Run
- 비동기 태스크 실행:
- Task.Run은 태스크를 생성하고 즉시 실행합니다. 내부적으로 Task.Factory.StartNew를 호출하여 스레드 풀에서 실행합니다.
- 가장 간단한 태스크 실행 방식입니다.
-
Task.Run(() => TaskMethod("Task 3"));
- 비동기 태스크 실행:
- Task.Factory.StartNew
- Task.Factory.StartNew는 태스크를 생성하고 바로 실행합니다.
- 두 번째 태스크에서는 TaskCreationOptions.LongRunning을 사용했는데, 이는 태스크가 스레드 풀이 아닌 전용 스레드에서 실행되도록 지정합니다.
- 용도: 태스크가 오래 실행되거나 CPU를 많이 사용하는 작업일 경우, 다른 스레드 풀 작업에 영향을 주지 않기 위해 사용합니다.
- Thread.Sleep
- 메인 스레드를 1초 동안 중단하여 모든 태스크가 실행을 완료할 시간을 줍니다.
-
Thread.Sleep(TimeSpan.FromSeconds(1));
빌드 결과 예상
출력은 태스크 실행 순서가 보장되지 않기 때문에 실행마다 다를 수 있습니다. 대략적인 출력 예시는 아래와 같습니다:
Task 2 is running on thread id 3. Is thread pool thread : True
Task 1 is running on thread id 4. Is thread pool thread : True
Task 3 is running on thread id 5. Is thread pool thread : True
Task 4 is running on thread id 6. Is thread pool thread : True
Task 5 is running on thread id 7. Is thread pool thread : False
태스크 생성과 관련된 핵심 개념
- Task 생성
- Task는 작업 단위를 정의하는 객체입니다.
- 태스크는 생성 후 실행(Start())을 명시적으로 호출해야 실행됩니다.
- Task.Run
- 태스크를 생성하고 즉시 실행합니다.
- 가장 간단하고 일반적인 태스크 실행 방식입니다.
- Task.Factory.StartNew
- Task.Run과 유사하지만 더 세부적인 옵션을 제공합니다.
- 옵션:
- TaskCreationOptions.LongRunning: 전용 스레드에서 실행.
- TaskCreationOptions.PreferFairness: 태스크가 가능한 한 공정하게 실행되도록 요청.
- 스레드 풀(Thread Pool)
- 대부분의 태스크는 스레드 풀에서 실행됩니다.
- 스레드 풀은 작업을 효율적으로 관리하며, 가벼운 태스크에 적합합니다.
- 전용 스레드
- TaskCreationOptions.LongRunning은 스레드 풀 대신 전용 스레드를 생성합니다.
- 리소스를 많이 사용하거나 오래 실행되는 작업에 적합합니다.
Task.Run vs Task.Factory.StartNew
특징 Task.Run Task.Factory.StartNew
코드 간결성 | 간결함 | 세부 옵션 제공 가능 |
비동기 작업 | 주로 사용됨 | 비동기 및 세부 조정 가능 |
옵션 지원 | 옵션 지원하지 않음 | LongRunning, PreferFairness 등 |
사용 추천 | 일반적인 태스크 실행에 적합 | 세부 동작 제어가 필요한 경우 |
어떤 태스크 생성 방식을 써야 할까?
- 간단한 태스크:
- Task.Run을 사용하세요.
- 예: 비동기 작업을 빠르게 시작할 때.
- 세부 설정 필요:
- Task.Factory.StartNew를 사용하세요.
- 예: 오래 실행되는 태스크(LongRunning)나 공정성을 강조하는 작업(PreferFairness).
- 성능 고려:
- 스레드 풀이 효율적이라면 Task.Run 또는 기본 Task.Factory.StartNew를 사용합니다.
- 전용 스레드가 필요하면 TaskCreationOptions.LongRunning을 사용합니다.
결론
- 이 코드에서는 다양한 태스크 생성 방식을 보여주고 있습니다.
- 일반적인 작업은 Task.Run을 사용하고, 세부 제어가 필요한 경우 Task.Factory.StartNew를 활용합니다.
- TaskCreationOptions.LongRunning은 스레드 풀이 아닌 전용 스레드에서 태스크를 실행하기 위해 사용됩니다.
추가적으로 궁금한 점이 있다면 언제든 물어보세요! 😊
반응형
'C# > 쓰레드' 카테고리의 다른 글
1. C# 스레드 생성과 병렬 처리 이해 (0) | 2025.01.24 |
---|---|
4. 태스크 병렬 라이브러리 (0) | 2025.01.20 |
C# 태스크(Task)와 비동기 프로그래밍: 생성, 연속 작업, 부모-자식 관계 이해 (0) | 2025.01.20 |
C# Task 기본 동작과 스레드 실행 시나리오 이해 (12) | 2025.01.17 |
C# `Thread`와 `ThreadPool`의 차이점 및 델리게이트 비동기 호출 이해 (16) | 2025.01.16 |
C# 스레드풀(Thread Pool): 개념, 사용법, 및 예제 코드 설명 (1) | 2025.01.16 |
C# SemaphoreSlim: 멀티스레드 리소스 접근 제어 예제와 설명 (1) | 2025.01.16 |
C# 스레드 제어: Semaphore와 SemaphoreSlim의 차이와 사용법 (2) | 2025.01.16 |