swift - 在主线程上使用 NSLock 安全吗?
问题描述
我有一个可以从多个线程访问的全局变量,包括从主线程。我想使用 NSLock因为它比 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
并且应该诉诸排队吗?
解决方案
是的,NSLock
从任何线程(包括主线程)使用都是安全的。唯一的限制NSLock
是你必须从你锁定它的同一个线程解锁它,你在这里做的。
会
NSLock
阻塞主线程还是在主线程上使用安全?
显然,如果您长时间阻塞主线程,那将是有问题的。因此,请确保您始终快速进出。始终避免长时间锁定(或阻塞)。
这也是同样的情况
DispatchSemaphore
并且应该诉诸排队吗?
任何同步机制都可能阻塞正在使用它们的线程,因此无论同步机制如何,它都存在很大问题。DispatchSemaphore
或 GCD 串行队列都将具有与此锁定模式相同的问题。
您始终可以使用读写器模式,这会稍微缓解这种情况(它允许并发读取并且只阻止写入)。
但作为一般规则,请限制您在同步机制中的工作量。例如,如果您正在做一些昂贵的事情,请尽可能多地在特定线程的本地执行,并且只同步共享资源的最终更新。
推荐阅读
- axios - 从函数参数向 axios http 请求发送数据
- sql - 如何根据两列最大值获取最新记录
- javascript - 由于缺少 http 模块,Electron/Angular 应用程序无法编译
- google-sheets - 使用查询从特定列中选择特定行和行范围
- visual-studio - 当sql server和wcf的主机不同时如何在visual studio中实现服务
- r - 如何在数据框的列上使用 R 的 diff 函数,条件是在不同列中具有特定值
- ios - Swift Firebase iOS didReceiveRemoteNotification 从不调用
- python - 引用框架内的标签
- kubernetes - 从 AWS EKS Autoscaler 工作程序节点中的私有 Docker 注册表中提取映像
- azure - 逻辑应用检查谁阅读了 yammer 帖子