Swift 3에서의 동기화 처리 (배타 제어)의 기본
getter는 sync에서 Swift 같은 락이 되어도 좋지만( ´・‿・`) htps // t. 코 / X2 rjyBmH7 — mono( ´・‿・`)🐶🍎📱⌚️ (@_mono) htps // t. 코 / 77 ~ ↑ GLj
참고 : August 7, 2016
과거의 방법
WWDC 슬라이드의 pp.120-123에 실려 있으므로 봐 주세요.
Concurrent Programming With GCD in Swift 3 - WWDC 2016 - Videos - Apple Developer
WWDC에서 권장하는 DispatchQueue.sync를 사용하는 방법
기본적으로 여기가 좋은 것 같습니다. 사실, 취급도 간단합니다.
class Account {
private var _balance: Int = 0
// デフォルトは、シリアルキュー
private let lockQueue = DispatchQueue(label: "Account lock serial queue")
// attributesに.concurrentを指定すると並行処理されるキューとなり同期処理の用途には不適切
// private let queue = DispatchQueue(label: "", attributes: .concurrent)
var balance: Int {
// getterを同期処理に
// クロージャー内で返した型をgetterの戻り値として返せる
get {
return lockQueue.sync { _balance }
}
// setterを同期処理に
set {
lockQueue.sync { _balance = newValue }
}
}
// _balanceの増減操作をするには読み取りと書き込みをセットで括る必要あり
func add(_ value: Int) {
lockQueue.sync { _balance += value }
}
}
포인트는 다음과 같습니다.
기본적으로 여기가 좋은 것 같습니다. 사실, 취급도 간단합니다.
class Account {
private var _balance: Int = 0
// デフォルトは、シリアルキュー
private let lockQueue = DispatchQueue(label: "Account lock serial queue")
// attributesに.concurrentを指定すると並行処理されるキューとなり同期処理の用途には不適切
// private let queue = DispatchQueue(label: "", attributes: .concurrent)
var balance: Int {
// getterを同期処理に
// クロージャー内で返した型をgetterの戻り値として返せる
get {
return lockQueue.sync { _balance }
}
// setterを同期処理に
set {
lockQueue.sync { _balance = newValue }
}
}
// _balanceの増減操作をするには読み取りと書き込みをセットで括る必要あり
func add(_ value: Int) {
lockQueue.sync { _balance += value }
}
}
포인트는 다음과 같습니다.
lockQueue
필드)를 작성해, 그것을 동기 처리에 사용한다 lockQueue.sync
로 처리를 묶는 것만으로 동기 처리 할 수있다 또,
sync
메소드는, 몇개의 오버로드가 있어, 반환값을 돌려줄 수도 있어, 위의 예에서는 balance 의 get
의 반환값 없는 쪽이 사용되고 있습니다.public func sync(execute block: () -> Swift.Void)
public func sync<T>(execute work: () throws -> T) rethrows -> T rethrows -> T
간단하게 테스트해 보면, 무사히 배타 제어되고 있는 것을 확인할 수 있습니다.
(아래 예에서는
balance
의 get
let account = Account()
for i in 0..<1_000 {
DispatchQueue.global().async {
account.add(10)
// 次のように同期処理を介さず操作すると最終結果がズレる(低くなる)
//account.balance += 10
}
}
Thread.sleep(forTimeInterval: 1)
print("final balance: \(account.balance)") // 10 x 1_000 = 10_000
그러나 성능은 좋지 않다.
퍼포먼스는 로우 레벨의 락 기법에 비해 나쁜 것 같습니다만, 안전・간단하므로, 그 근처가 아무래도 신경이 쓰이는 처리 이외는, Apple 추천의 set
를 사용하는 것이 좋을까라고 생각하고 있습니다.
혹은,
DispatchQueue.sync
에서는 요건 채울 수 없을 때도, 로우 레벨의 다른 방법을 사용할 필요가 되어 온다고 생각합니다.
Reference
이 문제에 관하여(Swift 3에서의 동기화 처리 (배타 제어)의 기본), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/mono0926/items/45413be5aa64128bc6d2텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)