swift 为读取操作调用DispatchQueue同步是否安全?[duplicate]

xdnvmnnf  于 2023-03-07  发布在  Swift
关注(0)|答案(1)|浏览(82)
    • 此问题在此处已有答案**:

Create thread safe array in Swift(16个答案)
2天前关闭。
我有一个使用串行调度队列读写字典的类。虽然写操作是异步的,但读操作是同步的。我想避免使用完成处理程序来读取。这会产生任何问题吗?问题可能包括死锁或从主线程调用时崩溃。

public final class UserRegistry {

    private var infoMap: [String: User] = [:]

    
    private let queue: DispatchQueue = .init(label: "userRegistry.queue")

    func register(_ user: User) {
        queue.async { [weak self] in
            self?.infoMap[user.id] = user
        }
    }

    func deregister(_ user: User) {
        queue.async { [weak self] in
            self?.infoMap[user.id] = nil
        }
    }

    func getUser(for id: String) -> User? {
        queue.sync {
            infoMap[id]
        }
    }
}

我试图创建一个完成处理程序,这将导致整个代码库中调用点的一系列更改。我希望同步读取应该是安全的,无论使用者从哪个线程调用它。

  • 读取操作 *-func getUser(for id: String) -> User?
  • 写入操作 *-func register(_ user: User)func deregister(_ user: User)
k2fxgqgv

k2fxgqgv1#

是的,您可以安全地使用sync进行读取,使用async进行写入,并且infoMap上不会有任何死锁或争用。
您甚至不需要特别使用[weak self],因为捕获self的块不会存在很长时间。
你也可能不需要使用async来写,你也可以只使用sync来写,因为infoMap不会被复制,所以不会有任何写时复制,而且很少会被重新分配,所以写操作应该总是足够便宜,可以同步运行。
请记住,如果User是一个引用类型(或者没有值语义),那么仍然可能存在涉及单个User对象的争用。

相关问题