study record
[Swift] Actor란? - 1 본문
우리가 쓰레드 문제를 생각하게 되면 동기화 문제, 즉 여러 쓰레드에서 같은 데이터에 동시에 접근해서 충돌, 문제가 발생하는 것이 있다.
동일한 데이터에 접근하여 여러 곳에서 값을 변화시키다 보면 동기화 문제가 발생한다.
이를 디버깅하는 것은 어렵다.
이러한 동기화 문제를 피하기 위한 방법 중 하나로 Actor라는 개념이 있다.
다른 방법에는 (let 사용, 값 타입 사용(class를 struct로 변경 등), serial dispatchQueue 사용(매번 반드시 신중히 써야 한다.))
Actor
Actor는 shared mutable state에 대한 동기화 메커니즘이다. Actor는 자신만의 상태를 가지며, 이 상태에 접근하는 유일한 방법은 Actor를 거치는 것이다. lock이나 serial dispatchQueue와 같이 Actor의 상태에 동시에 접근하지 않도록 한다. 이를 Swift가 근본적으로 보장한다.
Actor 사용하기
- Actor는 Swift의 새로운 타입이다. 클래스와 가장 유사하다.
- 다른 타입들과 같이 Extension, 이니셜라이저, 프로토콜 준수 다 가능하다.
- 참조 타입이다. 클래스와 비슷하다.
- 다만 클래스와 달리 상속을 지원하지 않는다.
- Actor는 한 번에 하나의 작업만 mutable state에 접근할 수 있도록 허용한다.
actor Card {
var id: Int = 0
func increment() {
self.count += 1
}
}
actor는 increment 메서드가 호출될 때 actor에서 다른 코드가 실행되지 않고 완료된다. 한 번에 하나의 접근만 실행한다.
여러 작업이 들어오면 한 작업할 때에 다른 작업은 기다려야 한다.
이를 위해서 Actor는 보통 외부에서 호출 시에 async/await과 함께 쓰게 된다.
외부에서 Actor를 사용할 때에 한 번에 하나의 접근식을 보장하기 위해서 비동기식으로 수행하기 때문이다.
Actor isolation
Actor islolation 이라는 개념은 위에서 말해 온 Actor가 mutable state를 보호하는 방법이다. 즉, 한 번에 하나만 접근하는 것을 수행하는 방식이다.
만약 actor에서 인스턴스를 받아 같은 프로퍼티에 대해 접근하고 업데이트 시키고자 하면 컴파일에러가 난다.
왜냐하면 actor의 프로퍼티는 actor-isolated property이기 때문이다.
이 actor-isolated property는 특정 actor 내에서 접근할 수 있다. -> self이다.
그래서 인스턴스를 받아서 그 프로퍼티를 수정하는 행동이 불가하다.
cross-actor reference
actor 외부에서 actor-isolated 정의에 대해 참조하는 것을 cross-actor reference라고 한다.
두 가지 경우가 있다.
불변 상태에 대한 cross-actor reference: actor가 정의된 동일 모듈의 어디에서나 항상 허용
actor BankAccount {
let accountNumber: Int
var balance: Double
init(accountNumber: Int, initialDeposit: Double) {
self.accountNumber = accountNumber
self.balance = initialDeposit
}
}
accountNumber의 경우 불변 상태, 즉 let으로 선언되어 있으므로 허용한다.
actor가 정의되지 않은 다른 모듈에서는 허용이 안 된다. 다른 모듈에서는 비동기 호출로 참조해야 한다.
비동기 호출로 수행하는 방법
비동기 함수 호출은 actor가 안전하게 수행할 수 있을 때 해당 작업을 실행하도록 요청한다.
비동기함수 호출을 시작한 자는 이를 처리할 수 있을 때까지 일시중단될 수 있다. 이를 처리할 수 있을지를 판단하는 actor측에서 순차적으로 확인하고 처리하므로 actor가 한 번에 하나의 작업을 처리할 수 있다.
참고
'Swift > 스위프트 정리' 카테고리의 다른 글
[Swift] Combine 연산자와 CheckedContinuation (0) | 2023.01.29 |
---|---|
[Swifit] Combine 기본 예제 (0) | 2023.01.15 |
[Swift] SwiftUI란? (0) | 2022.11.23 |
[Swift] Concurrency 사용하기 (0) | 2022.11.15 |
[Swift] Concurrency - 2 (1) | 2022.11.12 |