Swift 3 - 原子布尔值
Swift 3 - Atomic boolean
有人知道如何在 iOS 10 中创建原子布尔值吗?
当前代码:
import UIKit
struct AtomicBoolean {
fileprivate var val: UInt8 = 0
/// Sets the value, and returns the previous value.
/// The test/set is an atomic operation.
mutating func testAndSet(_ value: Bool) -> Bool {
if value {
return OSAtomicTestAndSet(0, &val)
} else {
return OSAtomicTestAndClear(0, &val)
}
}
/// Returns the current value of the boolean.
/// The value may change before this method returns.
func test() -> Bool {
return val != 0
}
}
代码按预期工作,但我不断收到警告:
'OSAtomicTestAndSet' was deprecated in iOS 10.0: Use atomic_fetch_or_explicit(memory_order_relaxed) from <stdatomic.h> instead
我无法让它与 atomic_fetch_or_explicit(memory_order_relaxed) 一起工作。
有谁知道如何将我当前的代码转换为 iOS10,以消除此警告?
谢谢!
更好的方法是避免它...如果您想模仿它只是为了同步对您的 AtomicBoolean 的访问,请使用 GCD 中可用的同步
例如
import PlaygroundSupport
import Foundation
import Dispatch
PlaygroundPage.current.needsIndefiniteExecution = true
let q = DispatchQueue(label: "print")
struct AtomicBoolean {
private var semaphore = DispatchSemaphore(value: 1)
private var b: Bool = false
var val: Bool {
get {
q.async {
print("try get")
}
semaphore.wait()
let tmp = b
q.async {
print("got", tmp)
}
semaphore.signal()
return tmp
}
set {
q.async {
print("try set", newValue)
}
semaphore.wait()
b = newValue
q.async {
print("did", newValue)
}
semaphore.signal()
}
}
}
var b = AtomicBoolean()
DispatchQueue.concurrentPerform(iterations: 10) { (i) in
if (i % 4 == 0) {
_ = b.val
}
b.val = (i % 3 == 0)
}
打印
try get
try set false
try set false
try set true
did false
got false
try get
try set true
did false
try set false
did true
did true
try set true
try set false
got false
try set false
did false
try get
did true
try set true
did false
did false
got false
try set false
did true
did false
苹果在Swift中确认Bool值的读写不是原子操作。
但是同步的方式有很多种
例子
在某处添加以下全局函数逻辑:
func synchronized<T>(_ lock: AnyObject, _ body: () throws -> T) rethrows -> T {
objc_sync_enter(lock)
defer { objc_sync_exit(lock) }
return try body()
}
并像这样使用:
let myLock = NSObject();
// ...
synchronized(myLock) {
// Something not thread safe here...
}
您的第一个选择是...
- 只需使用普通锁来保护您的值访问,另一个是...
- 使用Swift Atomics
那你可以直接说
var value = ManagedAtomic<UInt8>(0)
// Atomic store
value.store(2, ordering: .relaxed)
// Atomic load
value.load(ordering: .relaxed)
有人知道如何在 iOS 10 中创建原子布尔值吗?
当前代码:
import UIKit
struct AtomicBoolean {
fileprivate var val: UInt8 = 0
/// Sets the value, and returns the previous value.
/// The test/set is an atomic operation.
mutating func testAndSet(_ value: Bool) -> Bool {
if value {
return OSAtomicTestAndSet(0, &val)
} else {
return OSAtomicTestAndClear(0, &val)
}
}
/// Returns the current value of the boolean.
/// The value may change before this method returns.
func test() -> Bool {
return val != 0
}
}
代码按预期工作,但我不断收到警告:
'OSAtomicTestAndSet' was deprecated in iOS 10.0: Use atomic_fetch_or_explicit(memory_order_relaxed) from <stdatomic.h> instead
我无法让它与 atomic_fetch_or_explicit(memory_order_relaxed) 一起工作。
有谁知道如何将我当前的代码转换为 iOS10,以消除此警告?
谢谢!
更好的方法是避免它...如果您想模仿它只是为了同步对您的 AtomicBoolean 的访问,请使用 GCD 中可用的同步
例如
import PlaygroundSupport
import Foundation
import Dispatch
PlaygroundPage.current.needsIndefiniteExecution = true
let q = DispatchQueue(label: "print")
struct AtomicBoolean {
private var semaphore = DispatchSemaphore(value: 1)
private var b: Bool = false
var val: Bool {
get {
q.async {
print("try get")
}
semaphore.wait()
let tmp = b
q.async {
print("got", tmp)
}
semaphore.signal()
return tmp
}
set {
q.async {
print("try set", newValue)
}
semaphore.wait()
b = newValue
q.async {
print("did", newValue)
}
semaphore.signal()
}
}
}
var b = AtomicBoolean()
DispatchQueue.concurrentPerform(iterations: 10) { (i) in
if (i % 4 == 0) {
_ = b.val
}
b.val = (i % 3 == 0)
}
打印
try get
try set false
try set false
try set true
did false
got false
try get
try set true
did false
try set false
did true
did true
try set true
try set false
got false
try set false
did false
try get
did true
try set true
did false
did false
got false
try set false
did true
did false
苹果在Swift中确认Bool值的读写不是原子操作。
但是同步的方式有很多种
例子
在某处添加以下全局函数逻辑:
func synchronized<T>(_ lock: AnyObject, _ body: () throws -> T) rethrows -> T {
objc_sync_enter(lock)
defer { objc_sync_exit(lock) }
return try body()
}
并像这样使用:
let myLock = NSObject();
// ...
synchronized(myLock) {
// Something not thread safe here...
}
您的第一个选择是...
- 只需使用普通锁来保护您的值访问,另一个是...
- 使用Swift Atomics
那你可以直接说
var value = ManagedAtomic<UInt8>(0)
// Atomic store
value.store(2, ordering: .relaxed)
// Atomic load
value.load(ordering: .relaxed)