ric*_*ick 16 concurrency mutual-exclusion ios swift swift3
我有多个线程之间的共享内存.我想阻止这些线程同时访问这段内存.(像生产者 - 消费者问题)
问题:
线程向队列添加元素,另一个线程读取这些元素并删除它们.他们不应该同时访问队列.
该问题的一个解决方案是使用Mutex.
正如我发现的那样,Swift中没有Mutex.Swift还有其他选择吗?
Dev*_*ini 10
有很多解决方案,但是我将串行队列用于此类操作:
let serialQueue = DispatchQueue(label: "queuename")
serialQueue.sync {
//call some code here, I pass here a closure from a method
}
Run Code Online (Sandbox Code Playgroud)
编辑/更新:也用于信号量:
let higherPriority = DispatchQueue.global(qos: .userInitiated)
let lowerPriority = DispatchQueue.global(qos: .utility)
let semaphore = DispatchSemaphore(value: 1)
func letUsPrint(queue: DispatchQueue, symbol: String) {
queue.async {
debugPrint("\(symbol) -- waiting")
semaphore.wait() // requesting the resource
for i in 0...10 {
print(symbol, i)
}
debugPrint("\(symbol) -- signal")
semaphore.signal() // releasing the resource
}
}
letUsPrint(queue: lowerPriority, symbol: "Low Priority Queue Work")
letUsPrint(queue: higherPriority, symbol: "High Priority Queue Work")
RunLoop.main.run()
Run Code Online (Sandbox Code Playgroud)
正如人们评论的那样(包括我),有几种方法可以实现这种锁定。但我认为 dispatch semaphore 比其他的更好,因为它似乎开销最少。正如在 Apples文档“替换信号量代码”中发现的那样,除非信号量已经锁定(= 零),否则它不会进入内核空间,这是代码进入内核以切换线程的唯一情况。我认为信号量大部分时间都不是零(不过,这当然是特定于应用程序的问题)。因此,我们可以避免大量开销。
另一个关于 dispatch semaphore 的评论,与上面的场景相反。如果你的线程有不同的执行优先级,并且更高优先级的线程不得不长时间锁定信号量,调度信号量可能不是解决方案。这是因为等待线程之间没有“队列”。在这种情况下发生的情况是,高优先级线程在大部分时间获取并锁定信号量,而低优先级线程只能偶尔锁定信号量,因此,大多数情况下只是等待。如果此行为对您的应用程序不利,则必须考虑使用调度队列。
感谢beshio的评论,您可以像这样使用信号量:
let semaphore = DispatchSemaphore(value: 1)
Run Code Online (Sandbox Code Playgroud)
在使用资源之前使用等待:
semaphore.wait()
// use the resource
Run Code Online (Sandbox Code Playgroud)
并在使用release之后:
semaphore.signal()
Run Code Online (Sandbox Code Playgroud)
在每个线程中执行此操作。
归档时间: |
|
查看次数: |
6166 次 |
最近记录: |