Swift는 구조화된 방식으로 비동기와 병렬 코드 작성을 지원
동시성과 스레드 작업
- Swift의 동시성 모델은 스레드의 최상단에 위치하지만 직접 상호작용하지는 않음
- 비동기 함수는 실행중인 스레드를 포기 가능
- 포기 시 첫 번째 함수가 차단되는 동안 해당 스레드에서 다른 비동기 작업을 실행 가능
클로저를 이용해 비동기 작업을 진행할 수 있지만, 코드에 클로저가 많아지면 다루기 어려워지므로 동시성에 대한 언어 지원을 사용하여 해결 가능
비동기 함수는 실행 도중에 일시적을 중단될 수 있는 특수한 함수
async
키워드를 작성func asyncFunction(...) [async] [throws] [-> Value]
비동기 함수를 호출하면 해당 메서드가 반환될 때 까지 실행이 정지await
키워드로 작성func downloadFirstPhoto() async -> Photo {
let photoNames = await listPhotos(inGallery: "Summer Vacation")
let sortedNames = photoNames.sorted()
let name = sortedNames[0]
let photo = await downloadPhoto(named: name)
return photo
}
await
까지 진행, listPhotos(inGallary:)
가 반환될 때 까지 실행 중단listPhotos(inGallary:)
가 반환되면 코드를 이어서 실행await
인 downloadPhoto(named:)
가 반환될 때 까지 실행 중단downloadPhoto(named:)
가 반환되면 photo를 반환await
를 만나면 Swift가 현재 스레드에서 다른 코드를 실행하기 때문에 스레드 양보(yielding the thread)라고 부름
await
는 코드의 실행을 중단할 수 있어야 하므로 프로그램의 특정 위치에서만 비동기 함수를 호출 가능
@main
으로 표시된 구조체, 클래스enum
의 정적 main()
메서드에 있는 코드Task
의 코드
Task.sleep(_:)
아무런 동작도 하지 않고 주어진 나노 단위의 초만큼 대기
네트워크 작업 등 시간이 오래 걸리는 작업을 테스트할 때 유용
비동기 시퀀스로 한 번에 컬렉션의 한 element를 기다리는 것
for-in
대신 for-await-in
을 사용let firstTask = await longTask(order: 1)
let secondTask = await longTask(order: 2)
let thirdTask = await longTask(order: 3)
let tasks = [firstTask, secondTask, thirdTask]
위 코드는 하나의 longTask(order:)
이 완료되기 전 까지 다음 작업이 불가능하지만, 동시에 3개의 작업을 수행하면 매우 효율적
async let firstTask = longTask(order: 1)
async let secondTask = longTask(order: 2)
async let thirdTask = longTask(order: 3)
let tasks = await [firstTask, secondTask, thirdTask]
위 코드는 각 longTask(order:)
에 await
이 없기 때문에 각각의 작업이 완료될 때 까지 실행을 중단하지 않음
await
에서 3개의 작업을 동시에 수행async-let
을 사용Task
는 비동기적으로 실행할 수 있는 작업 단위
Task Group
에 Task
를 추가하면 우선순위와 취소를 쉽게 제어할 수 있으며, 동적으로 작업의 수를 제어 가능
Task
는 계층 구조로 정렬TaskGroup
의 각 Task
에는 동일한 상위 Task
가 있으며, 각 Task
는 하위 Task
가 있을 수 있다.TaskGroup과 달리 상위 작업이 존재하지 않음
Task.init(priority:operation:)
을 호출해 현재 actor에서 실행될 Unstructured Task를 생성Task.detached(priority:operation:)
을 호출해 현재 actor의 일부가 아닌 Unstructured Task를 생성Swift Concurrency는 협동 취소 모델(cooperative cancellation model)을 사용
CancellationError
등의 에러 발생nil
또는 []
반환Task.checkCancellation()
또는 Task.isCancelled
로 취소를 확인Task.cancel()
로 수동으로 취소actor
은 클래스와 마찬가지로 참조 타입
actor
의 동일한 인스턴스에 접근하는 것에 대한 안전을 보장actor
의 외부에서 await
없이 프로퍼티에 접근 불가능