我有一个全局变量,可以从多个线程(包括主线程)进行访问。我想使用NSLock because it’s faster than GCD。
这就是我想要做的:
struct SynchronizedLock<Value> {
private var _value: Value
private var lock = NSLock()
init(_ value: Value) {
self._value = value
}
var value: Value {
get { lock.synchronized { _value } }
set { lock.synchronized { _value = newValue } }
}
mutating func synchronized<T>(block: (inout Value) throws -> T) rethrows -> T {
return try lock.synchronized {
try block(&_value)
}
}
}
extension NSLocking {
func synchronized<T>(block: () throws -> T) rethrows -> T {
lock()
defer { unlock() }
return try block()
}
}
NSLock
会阻塞主线程还是在主线程上使用安全? DispatchSemaphore
的情况也是如此,应该诉诸队列吗?
答案 0 :(得分:2)
是的,可以从任何线程(包括主线程)中使用NSLock
。 NSLock
的唯一限制是您必须从锁定它的同一线程中对其进行解锁。
NSLock
会阻塞主线程还是在主线程上使用安全?
很明显,如果您在任何长时间内都阻塞了主线程,那将是有问题的。因此,请确保您总是非常快速地进出。始终避免长时间锁定(或阻塞)。
DispatchSemaphore
的情况也是如此,应该诉诸队列吗?
任何同步机制都可以阻止正在使用它们的线程,因此无论采用哪种同步机制,这都存在很大的问题。 DispatchSemaphore
或GCD串行队列都将具有与此锁定模式相同的问题。
您始终可以使用读取器-写入器模式,此模式会稍有缓解(该模式允许并发读取并且仅阻止写入)。
但是,作为一般规则,请限制您在同步机制中执行的操作。例如。如果您要进行昂贵的工作,请在本地线程中对特定线程尽力而为,并仅同步共享资源的最终更新。