개발 언어 & 프레임워크/C# 프로그래밍 마스터하기
C#의 병렬 처리 완전 분석(Thread, Task, Parallel 성능 및 특징 비교)
프로잉2
2025. 5. 29. 21:00
728x90
📘 개념 요약
개념 | 설명 |
Thread | 저수준 병렬 처리 방식으로, 개발자가 직접 스레드 생성/관리 |
Task | .NET에서 제공하는 고수준 병렬 처리 방식으로, 스레드 풀 기반 |
Parallel | 반복 작업을 병렬로 쉽게 수행하기 위한 고급 API (내부적으로 Task 사용) |
💻 실제 코드 성능 비교 예제
// Thread 방식
for (int i = 0; i < 5; i++)
{
new Thread(() =>
{
Console.WriteLine($"[Thread] 작업 {i} - ID: {Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(200);
}).Start();
}
// Task 방식
for (int i = 0; i < 5; i++)
{
Task.Run(() =>
{
Console.WriteLine($"[Task] 작업 {i} - ID: {Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(200);
});
}
// Parallel 방식
Parallel.For(0, 5, i =>
{
Console.WriteLine($"[Parallel] 작업 {i} - ID: {Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(200);
});
🧠 성능 비교 (정량적 요약)
항목 | Thread | Task | Parallel.For |
생성 속도 | 느림 (새 스레드 생성) | 빠름 (스레드풀 재사용) | 매우 빠름 (Task 활용 최적화) |
메모리 사용 | 상대적으로 높음 | 적음 | 적음 |
스케줄링 | 개발자가 직접 관리 | .NET이 자동 관리 | 자동 병렬 분할 |
예외 처리 | try-catch 직접 필요 | 간편 (await, ContinueWith) | 약간 복잡함 |
컨트롤 | 높음 (우선순위 등) | 중간 (제한적 컨트롤) | 낮음 (고정된 패턴) |
확장성 | 낮음 (스레드 과다 시 시스템 부하) | 높음 | 높음 (병렬 루프 자동 분배) |
🧪 실제 성능 차이 실험 (예시 시나리오)
작업 수: 1000개, 각각 50ms 대기
- Thread:
- 생성 비용 ↑
- 컨텍스트 스위칭 많음 → CPU 부하 증가
- 스레드 개수 많아지면 성능 급하락
- Task:
- 스레드 풀 기반이라 리소스 절약
- 처리 속도 일정, 확장성 우수
- Parallel:
- CPU 코어 수만큼 자동 분할 실행
- 단순 반복문에서는 최강 성능
🔧 사용법 요약
사용 상황 | 추천 도구 |
스레드 우선순위 제어, 백그라운드 스레드 필요 | Thread 직접 사용 |
병렬 연산, 백그라운드 API 호출 | Task, Task.Run |
대량 반복 작업, 빠른 계산 | Parallel.For, Parallel.ForEach |
📝 결론 요약
- Thread는 지금은 거의 특수 상황에만 사용됨 (직접 스레드 제어 필요할 때)
- Task는 범용 병렬 처리 및 비동기 처리의 기본
- Parallel은 반복 작업의 병렬 최적화에 최적
💡 실무에서는 대부분 Task와 Parallel을 사용하며, Thread는 병렬 제어가 필요한 특수 케이스에서만 권장됩니다.
🏷 추천 태그
C#, Thread, Task, Parallel, 스레드 풀, 병렬처리, 멀티스레딩, 성능 비교, 비동기, Concurrency, 스레드 최적화
🎯 실전 팁
- async/await 기반 Task는 비동기 I/O 작업에 최적
- Parallel.For는 CPU 바운드 작업에 최적
- 병렬 작업 수가 많고 짧을수록 Task 또는 Parallel을,
작업 시간이 길고 독립적일수록 Thread를 사용하면 됩니다.
728x90