티스토리 뷰

Swift

[Swift] Concurrency(4) - Tasks and Task Groups

Kim_Baechu 2022. 12. 15. 00:53

Tasks and Task Groups

task는 프로그램의 일부(part)로 비동기적으로 실행될 수 있는 작업 단위입니다.

모든 비동기 코드는 일부 작업의 일부로 실행됩니다.

이전 섹션에서 설명한 async-let구문을 사용하면 하위 작업이 생성됩니다.

또한 태스크 그룹을 생성하고 해당 그룹에 하위 태스크를 추가하여 우선 순위 및 취소를 보다 효과적으로 제어하고 동적인 수의 태스크를 생성할 수 있습니다.

태스크는 계층 구조로 정렬됩니다.

태스크 그룹의 각 태스크에는 동일한 상위 태스크가 있으며 각 태스크에는 하위 태스크가 있을 수 있습니다.

태스크와 태스크 그룹 간의 명시적인 관계 때문에 이 접근 방식을 구조화된 동시성(structured concurrency)이라고 합니다.

작업 간의 명시적인 상위-하위 관계를 통해 Swift는 사용자를 위해 취소 전파와 같은 일부 동작을 처리하고 컴파일 시 일부 오류를 탐지할 수 있습니다.

await withTaskGroup(of: Data.self) { taskGroup in
    let photoNames = await listPhotos(inGallery: "Summer Vacation")
    for name in photoNames {
        taskGroup.addTask { await downloadPhoto(named: name) }
    }
}

Unstructured Concurrency

Swift는 이전 섹션에서 설명한 동시성에 대한 구조화된 접근 방식 외에도 구조화되지 않은 동시성도 지원합니다.

태스크 그룹의 일부인 태스크와 달리 구조화되지 않은 태스크(unstructured task)에는 상위 태스크가 없습니다.

프로그램에 필요한 모든 방식으로 비정형 작업을 관리할 수 있는 완벽한 유연성을 갖추고 있지만, 정확성에 대해서도 전적으로 책임을 져야 합니다.

현재 액터에서 실행되는 구조화되지 않은 작업을 만들려면 Task.init(priority:operation:) 이니셜라이저를 호출합니다.

현재 작업자의 일부가 아닌 구조화되지 않은 작업, 특히 분리된 작업을 만들려면 Task.detached(priority:operation:) 클래스 메서드를 호출합니다.

이러한 작업은 결과를 기다리거나 취소하는 등 상호 작용할 수 있는 태스크를 반환합니다.

let newPhoto = // ... some photo data ...
let handle = Task {
    return await add(newPhoto, toGalleryNamed: "Spring Adventures")
}
let result = await handle.value

Task Cancellation

Swift 동시성은 cooperative cancellation model을 사용합니다.

각 태스크는 실행 시 적절한 시점에 취소되었는지 확인하고 적절한 방법으로 취소에 응답합니다.

작업에 따라 일반적으로 다음 중 하나를 의미합니다.

  • 'CancellationError' 같은 오류를 throw
  • nil 또는 빈 컬렉션을 return
  • 부분적으로 완료된 작업을 return

취소 여부를 확인하려면 작업이 취소된 경우 CancelationError를 발생시키는 Task.checkCancelation()을 호출하거나 Task.isCancelled의 값을 확인하고 자신의 코드로 취소를 처리합니다.

예를 들어 갤러리에서 사진을 다운로드하는 작업은 부분 다운로드를 삭제하고 네트워크 연결을 닫아야 할 수 있습니다.

다음글

[iOS] Concurrency(5) - Actors

댓글
공지사항