슬슬 배우는 스위프트의 컨실러린시~ 후반~

10865 단어 Swiftconcurrencytech
이 글은 Swift/Kotlin 애호회 Advent Calendar 2021 5일째 글입니다!
이 글은 천천히 일본어로 읽은 것이다Swift.org의 Conceurncy.지금부터 Conceurrency를 배우실 분들은 이 글에서 내용을 대충 파악한 후 원문을 꼭 읽어주시기 바랍니다.
전반전여기.
다음 본문

Tasks 및 Task Groups


Task(작업)는 비동기적으로 수행할 수 있는 처리 단위입니다.모든 비동기 코드는 Task의 일부로 실행됩니다.async-let 문법은 하위 임무를 만드는 것이다.
Task Group(Task Group) 추가 하위 작업을 만들 수도 있습니다.이렇게 하면 우선순위와 취소를 더욱 상세하게 제어할 수 있다.
Task는 계층으로 구성됩니다.각 Task Group 의 Task 에는 부모 Task 가 있고 각 Task 에는 자식 Task 가 있습니다.
Task와 Task Group은 명확한 관계가 있기 때문에 이런 방법을 Structured Conceurrency(구조화된 병행성)라고 부른다.
프로그램의 정당성은 어느 정도 개발자의 보증이 필요하지만Task 간의 명확한 부자관계 덕분에 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) }
    }
}
자세한 내용은 TaskGroup를 보십시오.

비구조적 병행성


Swift는 위의 구조적 병행성을 구성하는 방법 외에도 비구조적 병행성을 지원합니다.비구조적인 Task에는 부모 Task가 없습니다.
Task 는 설치 요구 사항에 따라 유연하게 처리할 수 있지만 프로그램의 적법성은 개발자가 보장해야 합니다.
현재 Actor 에서 실행되는 비구조적 Task 를 만들려면 초기 프로그램 Task.init(priority:operation:) 이라고 합니다.
현재 Actor의 일부가 아닌 비구조적 Task(구체적으로 detached task라고 함)를 만들려면 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 처리 방법에 대한 자세한 내용은 Task를 참조하십시오.

Task 취소


Swift의 병행성은 조화로운 취소 모드를 채택했다.
각 Task는 실행 중인 시점에서 취소되었는지 확인하고 취소된 응답을 적절한 방법으로 반환합니다.보통 밑에 있는 거예요.

  • 던지기CancellationError 이런 오류
  • nil 또는 빈 모음집으로 돌아가기
  • 부분 완료 결과 반환
  • 취소 검사를 위해 취소CancellationError를 던지거나Task.checkCancellation() 검사Task.isCancelled의 값을 확인한 뒤 독자적으로 취소 처리하는 방법이 있다.
    예를 들어 갤러리에서 사진을 다운로드하는 Task는 다운로드한 데이터를 일부 삭제하고 네트워크 연결을 닫을 때가 있다.
    취소 정보를 수동으로 전파하기 위해 Task.cancel()라고 불러주세요.

    Actors


    클라스와 마찬가지로 액터(리액터)도 참조형이다.Classes Are Reference Types에서 비교한 값형과 참조형의 비교는 Class와 마찬가지로 Actor에 적용된다.
    Actor는 한 번에 하나의 작업에 대한 가변 상태만 액세스할 수 있으므로 동일한 Actor의 인스턴스를 여러 Task에서 안전하게 정리할 수 있습니다.예를 들어 기온을 기록하는 동작은 다음과 같다.
    actor TemperatureLogger {
        let label: String
        var measurements: [Int]
        private(set) var max: Int
    
        init(label: String, measurement: Int) {
            self.label = label
            self.measurements = [measurement]
            self.max = measurement
        }
    }
    
    actor는 키워드로 Actor를 정의할 수 있습니다.TemperatureLogger Actor의 경우 Actor 외부에서 액세스할 수 있는 속성이 있지만 Actor 내의 코드만 업데이트할 수 있는 최대 속성max으로 제한됩니다.
    Actor의 인스턴스는 Struct, Class와 같은 구문의 초기화기로 만들 수 있습니다.이후에 Actor의 등록 정보 및 메서드에 액세스할 때 일시 중지할 수 있는 점을 await로 지정합니다.이런 느낌.
    let logger = TemperatureLogger(label: "Outdoors", measurement: 25)
    print(await logger.max)
    // Prints "25"
    
    는 이 예logger.max에서 잠시 멈출 가능성이 있는 점이다.Actor는 한 번에 하나의 Task의 가변 상태만 액세스할 수 있으므로 다른 Task와 logger가 속성에 액세스할 때까지 대기를 일시 중지합니다.
    이에 비해 Actor의 코드에서 Actor의 속성에 액세스하는 경우await는 필요하지 않습니다.예를 들어 새로운 온도에서 갱신TemperatureLogger하는 방법은 이렇다.
    extension TemperatureLogger {
        func update(with measurement: Int) {
            measurements.append(measurement)
            if measurement > max {
                max = measurement
            }
        }
    }
    
    update(with:) 메서드는 Actor가 수행max 속성을 액세스할 때도 필요하지 않습니다await.
    이 메서드는 Actor가 Task에서 동시에 가변 상태로 전환할 수 있는 이유도 보여 줍니다.
    예를 들어 Actor의 상태를 업데이트하면 일시적인 불변성이 망가집니다.TemperatureLogger Actor는 새로운 측정 값을 기록할 때 최대 온도와 온도 목록을 추적합니다.업데이트 과정에서 새로운 측정치가 증가했고 업데이트max 이전TemperatureLogger에 일시적으로 일치하지 않은 상태였습니다.여러 Task 와 동일한 인스턴스에 대한 동시 변고가 발생하지 않도록 함으로써 다음과 같은 문제를 방지할 수 있습니다.
  • update(with:) 호출 방법, 먼저 measurements Aray
  • 를 업데이트합니다.

  • 업데이트max 전에 최대 및 온도의 Aray
  • 를 읽습니다.

  • 변경max으로 업데이트 완료
  • 이 경우 다른 곳에서 실행된 코드는 데이터가 일시적으로 유효하지 않은 상태update(with:)로 호출될 때 Actor에 대한 액세스가 삽입되기 때문에 잘못된 정보를 읽었습니다.
    Swift Actor를 사용하면 한 번에 하나의 작업만 수행할 수 있고 await가 있는 곳에서만 코드를 중단할 수 있기 때문에 이 문제를 방지할 수 있습니다.update(with:) 일시 정지점이 포함되지 않기 때문에 업데이트 도중에 다른 코드가 데이터에 접근할 수 없습니다.
    동작 이외의 속성에 접근하려면 컴파일 오류가 발생합니다.
    print(logger.max)  // Error
    
    Actor의 속성은 분리된 로컬 상태의 일부이므로 액세스할 수 없습니다await.Swift는 Actor 내의 코드만 Actor의 로컬 상태에 액세스하도록 보장합니다.이 보증은 logger.max (Actor의 격리) 라고 한다.
    본문 이상!

    좋은 웹페이지 즐겨찾기