首页 > 解决方案 > 在主线程上使用 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并且应该诉诸排队吗?

标签: swiftconcurrencygrand-central-dispatchnslock

解决方案


是的,NSLock从任何线程(包括主线程)使用都是安全的。唯一的限制NSLock是你必须从你锁定它的同一个线程解锁它,你在这里做的。

NSLock阻塞主线程还是在主线程上使用安全?

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

这也是同样的情况DispatchSemaphore并且应该诉诸排队吗?

任何同步机制都可能阻塞正在使用它们的线程,因此无论同步机制如何,它都存在很大问题。DispatchSemaphore或 GCD 串行队列都将具有与此锁定模式相同的问题。

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

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


推荐阅读