swift - 在主线程上使用 NSLock 安全吗?

标签 swift concurrency grand-central-dispatch nslock

我有一个全局变量,可以从多个线程访问,包括从主线程访问。我想使用 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 是否也是这种情况,是否应该求助于队列?

最佳答案

是的,从任何线程使用 NSLock 都是安全的,包括主线程。 NSLock 的唯一限制是您必须从锁定它的同一个线程解锁它,您正在此处执行此操作。

Would NSLock block the main thread or is it safe to use on the main thread?

显然,如果您长时间阻塞主线程,就会出现问题。因此,请确保您始终快速进出。始终避免长时间锁定(或阻塞)。

Also is this the same situation with DispatchSemaphore and should resort to queues?

任何同步机制都可能阻塞正在使用它们的线程,因此不管同步机制如何,它都会产生很大的问题。 DispatchSemaphore 或 GCD 串行队列都会遇到与此锁定模式相同的问题。

您始终可以使用读写器模式,这会稍微缓解这种情况(它允许并发读取并且只阻止写入)。

但作为一般规则,限制您在同步机制中执行的操作。例如。如果您正在做一些昂贵的事情,请在特定线程的局部范围内尽可能多地做,并且只同步共享资源的最终更新。

关于swift - 在主线程上使用 NSLock 安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58228284/

相关文章:

c - 线程并发C程序

go - 如何在不产生死锁的情况下拥有一个缓冲 channel 和多个读取器?

c# - 是什么阻止我的事件处理程序方法完成?

objective-c - 测试使用中央调度的 GUI 组件

multithreading - 我可以假设计划在串行队列上运行的 block 将全部在同一线程上运行吗?

html - 在 Swift 4 中将属性文本转换为 HTML

xcode - 我可以在 xcode 的不同文件夹中使用相同的文件名吗?如何使用 ios Swift 语言访问它

swift - 使用 Alamofire 上传多部分表单数据显示服务器中缺少文件

ios - SWIFT ImageView 上的随机/不规则脉冲动画

objective-c - __weak typeof(self)weakSelf = self或__weak MyObject * weakSelf = self?