[Swift] GCD와 swift concurrency가 나오게된 배경과, concurrency 기본개념

2026. 1. 19. 10:16·앱/Swift

Swift Concurrency 이전의 DispatchQueue (GCD)가 나오게 된 배경

이전의 Grand Central Dispatch(GCD)는 정확히 당신이 생각한 대로 thread pool을 시스템 레벨에서 관리하여 thread explosion을 방지하기 위해 만들어졌음

GCD 이전의 문제점들

Thread 직접 관리의 어려움:

  • 개발자가 직접 Thread를 생성하고 관리해야 했음
  • Thread 생성 비용이 높고(스택 메모리 할당, 커널 데이터 구조 등), 각 Thread마다 최소 512KB의 메모리 필요
  • Thread explosion: 동시성 작업이 많아지면 무분별하게 Thread가 생성되어 시스템 리소스 고갈

Apple 문서의 표현:

"In the past, introducing concurrency to an app required the creation of one or more additional threads. Unfortunately, writing threaded code is challenging. Threads are a low-level tool that must be managed manually."

 

GCD의 핵심 이점:

  1. Thread Pool 자동 관리: 시스템이 최적의 Thread 개수 결정
  2. Thread 재사용: 작업 완료 후 Thread를 풀에 반환
  3. Context Switching 최소화: 과도한 Thread 생성 방지
  4. 개발자 친화적: Thread 생명주기 관리 불필요

 

Swift Concurrency가 나오게 된 배경

GCD는 훌륭했지만, 10년 이상 사용하면서 근본적인 문제들이 있었고, 그걸 해결하기 위한 방법으로 Swift Concurrency가 나옴

문제는 다음과 같음

  1. allback hell ( 콜백지옥 ) - 가독성문제 
  2. 여전히 존재하는 thread explosion
  3. data race(경합)
  4. 취소와 우선순위의 관리 어려움 - 구조적 cancellation으로 해결
  5. UI 변경의 취약성 

 

Swift Concurrency의 혁신

Apple 문서:

"Swift Concurrency uses a cooperative thread pool. Instead of blocking threads, async functions suspend, allowing the thread to pick up other work."

 

위의 문제를 다음과 같이 해결함

  1. 콜백지옥 - 구조화된 동시성
  2. thread explosion - non blocking방식의 스레드 관리 
    • Thread Pool 크기는 CPU 코어 수로 고정 (기본적으로)
  3. 데이터 경합 - actor를 통해서 해결
  4. 취소와 우선순위 - Cancel의 전파
  5. UI 변경 취약성 - mainActor

 


비교 요약표

측면DispatchQueue (GCD)Swift Concurrency
Thread 관리 Thread Pool (수동 블로킹) Cooperative Thread Pool (자동 suspend)
가독성 Callback 중첩 async/await 순차적
Thread Explosion 블로킹 시 발생 가능 구조적으로 방지
Data Race 런타임 크래시 컴파일 타임 검증 (Actor)
취소 수동, 복잡 자동 전파 (Structured)
에러 처리 Result/completion throws/try-catch
UI 스레드 전환 수동 (DispatchQueue.main) 자동 (@MainActor)

Task

비동기 적인 일처리의 기본 단위

서로다른 Task는 병렬적으로 일처리 가능

비동기 함수는 Task내부에서만 호출 가능하다.(비동기 실행 환경을 만듬)

  • 비유하자면, Task는 DispatchWorkItem이면서 ( 취소가 가능하며 한개의 작업단위 ) , 병렬적인 작업 ( DispatchQueue) 의 합본같은 느낌이다. ( 물론 느낌만 그렇다는것 )

생성자

Task(priority: TaskPriority, operation: () async throws -> Sendable)
Task(priority: TaskPriority, operation: () async -> Sendable)

Task안에서는 순서를 가지만, 해당 Task는 한개의 작업단위로 각 스레드로 보내서 작업을 할수 있다.

Task의 특징 

  • Task자체는 cancle할수있다.
//작업 취소
task.cancle
  • Task값을 리턴하는것도 가능하다(generic으로 생성할수 있기 때문)
// Generic으로 리턴값을 정할수도 있다. 
let task: Task<String, Never> = Task { return String }
//task.value로 접근 가능
  • 작업은 우선순위를 가진다.
- userInitiated -25
- hight - 25
- medium - 21
- low - 17
- utiltiy - 17
- background - 9

기본값은 utility이다.

  • 작업은 실행 컨텍스트의 메타데이터를 그대로 상속해서 사용한다. - 굉장히 중요한 개념
    1. 우선순위
    2. 실행 액터
    3. 로컬변수
    4. 취소 - 는 상속되지 않는다.

하지만 해당 작업을 detached라는 함수를 통해서 독립적으로 실행되게 할수 있다. 이러한 경우에는 상속을 받지 않는다.

기존 GCD와의 차이 

간단한 예시 코드를 보면서 이해해보자

func someFunction() async -> String {
	sleep(5)
	try? await Task.sleep(.second(5))
	return "hi"
}

위의 함수를 보면 내부적으로 sleep(5)와 try? await Task.sleep()이 있다.

  • sleep의 경우가 기존의 GCD와 동일한 방식이라고 생각하면된다.
  • try? await이 이번에 생긴 async await 방식

뭐가다른가?

sleep의 경우에는 thread를 블락한다.

즉 해당 스레드는 5초간 아무일도 못하게 된다.

하지만 concurrency의 경우 해당 함수를 “잠깐 멈춰두고” 다른 일을 할수 잇게 된다.

에러처리

Task로 감싼 경우, 에러를 Task에서 처리해줄수 있다.

  • 최근에는 DispatchQueue.main.async를
  • await MainActor.run { } 을 사용하면됨

 

Continuation 사용

  • continuation객체란, 함수의 실행이 일시중단될때 현재 함수의 상태를 힙에 저장하게 되는데 이때, 지역변수 실행 위치등을 continuation객체에 저장하여 캡쳐하고, 이를 함수가 재개될때 해당 시점부터 시작될수 있도록 하는 객체이다. ( 사실상 그냥 suspension point) 
  • 그렇기 때문에 resume()이라는 메소드를 사용하게 되는것임.

continuation은 두개가 있는데

  1. checked continuation : 컴파일타임에 resume이 두개 실행됐는지 확인
  2. unsafe continuation : resume이 두개 있는지 런타임에 확인

 

continuation을 통해서 delegate를 concurrency 형태로 사용할수 있도록 하는

continuation 객체를 생성해서 사용할수 있다.

var checkedContinuation: CheckedContinuation<CLLocation, Error?>

func getCurrentLoaction() async throws {
	let location: CLlocation = try await withCheckedContinuation { continuation in 
		self.checkedContinuation = continuation
	}
}

checkedContinuation?.resume(with: .success(CLLocation()))

이러한 방식을 통해서 checkedContinuation을 밖에서 생성해두고, 해당 객체에 resume을 하는 타이밍을 넘기는것으로 delegate메소드 내에서 해당 메소드를 호출하면, 외부에 생성된 객체가 이벤트를 return해준다.

좀더 자세한 예시를 보자

  1. Delegate메소드를 사용하는 객체 생성
final class locationManager: NSObject, CLLocationManagerDelegate {}
  1. 해당 객체 내부에 continuation생성
var continuation: ChekcedThrowingContinuation<CLLocation, Error?>
  1. 해당 continuation을 외부에서 주입
    func getLocation() async {
    	do { 
    		let location = try await withCheckedContinuation { coninuation in 
    			locationManager.continuation = continuation
    			locaationManger.start()
    		}
    
  2. 주입해주는 시점은 비동기 메소드를 호출해주는시점에서 withCheckedContinuation 을 호출해서, continuation을 생성후 넘겨줌
  3. delegate 메소드 내부에서 continuation으로 값을 보내줌
  4. func loactionManager() { continuation?.resume(retiurning: location) continuation = nil }

만약 여러번의 위치를 받아오거나, 계속해서 값이들어오는경우에는 asnycStream으로 처리가능 (추후 작성하겠습니다. )

반응형
저작자표시 비영리 변경금지 (새창열림)

'앱 > Swift' 카테고리의 다른 글

[iOS] ReactorKit을 Combine으로 구현하는 법  (0) 2026.01.18
[iOS] moya를 combine을 이용해서 구현해보자  (0) 2026.01.18
Reactorkit의 Pulse 구현부에 대해서  (0) 2025.02.18
Moya Mock Data 사용하기(feat. test Double)  (0) 2025.01.31
reactorkit에서 testcode 작성 하는법(feat. nimble)  (0) 2025.01.31
'앱/Swift' 카테고리의 다른 글
  • [iOS] ReactorKit을 Combine으로 구현하는 법
  • [iOS] moya를 combine을 이용해서 구현해보자
  • Reactorkit의 Pulse 구현부에 대해서
  • Moya Mock Data 사용하기(feat. test Double)
진ddang
진ddang
안녕하세요 진땅의 개발자 블로그 입니다. 피드백은 환영입니다. 깃헙 : https://github.com/it794613
    반응형
  • 진ddang
    맛동산이
    진ddang
  • 전체
    오늘
    어제
    • 분류 전체보기 (202)
      • 일기 그리고 목표 (1)
      • 웹 (20)
        • 리액트 (19)
      • 앱 (118)
        • Swift 문법 (15)
        • Swift (68)
        • SwiftUI (32)
        • 리액트 네이티브 (3)
      • CS (30)
        • 컴퓨터그래픽스 (8)
        • 운영체제 (6)
        • 네트워크 (16)
      • 알고리즘 (13)
        • 백준 (12)
        • 프로그래머스 (1)
      • 대외활동 (7)
        • ict한이음(2022.04) (2)
        • 멋쟁이 사자처럼 (5)
        • Apple Developer Academy (0)
      • 다양한 내용들 (8)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Swift
    스위프트
    멋쟁이사자처럼
    스유
    spritekit
    백준
    리액트
    컴퓨터그래픽스
    c++
    ReactorKit
    composable architecture
    cs
    SwiftUI
    운영체제
    웹
    Protocol
    대외활동
    영남대
    후기
    dispatchqueue
    네트워크
    멋사
    알고리즘
    uikit
    swift concurrency
    TCA
    widget
    위젯킷
    widgetkit
    문법
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
진ddang
[Swift] GCD와 swift concurrency가 나오게된 배경과, concurrency 기본개념
상단으로

티스토리툴바