【问题标题】:How to avoid deadlock calling custom DispatchQueue sync from main thread?如何避免死锁从主线程调用自定义 DispatchQueue 同步?
【发布时间】:2021-05-03 05:18:12
【问题描述】:

我正在尝试从多个线程安全地读取/写入数据,如下所述:Create thread safe array in Swift

这是我如何读取数据的 sn-p

    private let annotationsQueue = DispatchQueue(label: "myCustoLabel", attributes: .concurrent)
    private var unsafeAnnotations = [MapAnnotation]()
    private var annotations: [MapAnnotation] {
        var annotationsCopy: [MapAnnotation]!
        annotationsQueue.sync {
            annotationsCopy = self.unsafeAnnotations
        }
        return annotationsCopy
    }

我的问题是有时会从DispatchQueue.main.async 调用annotations,这会导致死锁。

这是堆栈跟踪的屏幕截图,当我到达死锁时

我的问题是我应该如何处理这种情况?我应该以某种方式强制我的annotationsQueue 在后台线程上运行吗? 或者我应该编写我的代码,所以永远不会从DispatchQueue.main.async 调用annotations

【问题讨论】:

  • 这里您阅读了一些注释数据。对? annotationsQueue.sync
  • @JatinRB 是的,我添加了屏幕截图以突出显示问题
  • 由于某种原因,低优先级任务将无法工作,所以请尝试像这样的 getter setter 方法stackoverflow.com/questions/35084754/…
  • 很简单。不要使用sync
  • 不,串行队列上的异步是一种锁定形式。但是你不能让它成为一个计算属性。

标签: swift asynchronous grand-central-dispatch


【解决方案1】:

当您创建并发队列时,可以使用调度屏障从多个线程读取/写入。

 private let annotationsQueue = DispatchQueue(label: "myCustoLabel", attributes: .concurrent)
   

private var unsafeAnnotations = [MapAnnotation]()

private var annotations: [MapAnnotation]? {
    var annotationsCopy: [MapAnnotation]!
    get {
      annotationsQueue.sync {
        return annotationsCopy
    }
    return nil

    }
    set {
      annotationsQueue.async(flag: .barrier) {
           annotationsCopy = self.unsafeAnnotations
       }
    }   

}

【讨论】:

    猜你喜欢
    • 2017-01-05
    • 1970-01-01
    • 2021-08-02
    • 2021-11-09
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多