
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 없이 프로퍼티에 접근 불가능