你使用GCD吗?不,我没有使用GDC.不必使用队列系统增加一个数字似乎是过度的.
你了解基本的线程安全吗?是的,否则我不会问原子增量.
>这个变量是本地的?没有.
>是实例级吗?是的,它应该是单个实例的一部分.
我想做这样的事情:
class Counter { private var mux Mutex private (set) value Int func increment (){ mux.lock() value += 1 mux.unlock() } }
There’s a long list of OSAtomicIncrement and OSAtomicDecrement
functions that allow you to increment and decrement an integer value
in an atomic way – thread safe without having to take a lock (or use
queues). These can be useful if you need to increment global counters
from multiple threads for statistics. If all you do is increment a
global counter,the barrier-free OSAtomicIncrement versions are fine,
and when there’s no contention,they’re cheap to call.
这些功能可以使用固定大小的整数,您可以选择
根据您的需要,32位或64位变体:
class Counter { private (set) var value : Int32 = 0 func increment () { OSAtomicIncrement32(&value) } }
(注:由于Erik Aigner正确注意到,OSAtomicIncrement32和
从MacOS 10.12 / iOS 10.10开始,朋友已被淘汰. Xcode 8建议使用< stdatomic.h>代替.但是这似乎很难,
比较Swift 3: atomic_compare_exchange_strong和https://openradar.appspot.com/27161329.
因此,以下基于GCD的方法似乎是最好的
解决方案.)
或者,可以使用GCD队列进行同步.
从Dispatch Queues在“并发编程指南”中:
… With dispatch queues,you could add both tasks to a serial
dispatch queue to ensure that only one task modified the resource at
any given time. This type of queue-based synchronization is more
efficient than locks because locks always require an expensive kernel
trap in both the contested and uncontested cases,whereas a dispatch
queue works primarily in your application’s process space and only
calls down to the kernel when absolutely necessary.
在你的情况下会是
// Swift 2: class Counter { private var queue = dispatch_queue_create("your.queue.identifier",DISPATCH_QUEUE_SERIAL) private (set) var value: Int = 0 func increment() { dispatch_sync(queue) { value += 1 } } } // Swift 3: class Counter { private var queue = DispatchQueue(label: "your.queue.identifier") private (set) var value: Int = 0 func increment() { queue.sync { value += 1 } } }
有关更复杂的例子,请参见Adding items to Swift array across multiple threads causing issues (because arrays aren’t thread safe) – how do I get around that?或GCD with static functions of a struct.这个线程
What advantage(s) does dispatch_sync have over @synchronized?也很有趣.