withThrowingTaskGroup 내부의 group.addTask 클로저는 어떤 스레드에서 실행될까요? 그리고 그 이유는 무엇인가요?
Swift Concurrency의 핵심에서 addTask가 부모 Actor의 isolation을 상속하지 않는 점이 병렬 실행의 핵심이에요.
이는 TaskGroup 내 작업들이 cooperative thread pool에서 독립적으로 실행되도록 설계된 결과로, @MainActor 컨텍스트를 벗어나 백그라운드에서 효율적으로 처리돼요.
Swift cooperative thead pool은 CPU 코어 수만큼만 스레드를 유지하며, 작업이 suspend/resume 될 때 자발적으로 제어권을 양보하는 구조에요.
일반 스레드풀과 달리 런타임이 suspension 포인트를 예측하여 최적화하므로 thread explosion을 방지해요. 이는 GCD의 단점을 보완한 방식이에요.
@MainActor class 안의 Task {}는 부모 isolation을 상속받아 메인스레드에서 실행되지만, group.addTask {} 는 nonisolated로 명시가 되어 isolation을 초기화해요. 이로 인해 child task는 actor 컨텍스트 없이 cooperative pool에서 병렬적으로 실행이 가능해요.

"병렬 처리를 위해 의도적으로 격리를 해제한다"는 점이 바로 Swift Concurrency 의 설계 방식이에요.
| 비교 항목 | GCD (기본 방식) | Cooperative Thread Pool (Swift 5.5+) |
|---|---|---|
| 스레드 생성 | 필요 시마다 생성 (제한 없음) | CPU 코어 수만큼만 유지 |
| 제어권 전환 | Context Switch (비용 높음) | Suspension Point (await)에서 자발적 양보 |
| 효율성 | 메모리 오버헤드 및 스케줄링 부하 발생 가능 | 시스템 자원을 최적으로 사용하며 폭주 방지 |