提问者:小点点

DispatchQueue.sync {}块"线程"或"队列"


我很困惑。

下面的代码肯定会导致死锁:

// Will execute
DispatchQueue.main.async { // Block 1 
  // Will execute
    DispatchQueue.main.sync { // Block 2
     // Will not be executed
    }
    // Will not be executed
}

因为

    < li >在主队列上分派_async后,它将第一个块提交给主队列执行 < li >有时,系统决定运行block1 < li > <代码>。sync方法阻止“线程/队列?”

我的问题是:同步会阻止它正在执行的当前线程还是当前队列?(我了解线程之间的区别

互联网上的大多数回答都说它会阻塞线程

>

  • 如果阻塞线程-

    如果阻塞队列-

    我发现了一些关于此的讨论:

    dispatch_sync内部dispatch_sync导致死锁

    DispatchQueue.sync 与 DispatchQueue.async的区别

    如果在同一队列上调度会发生什么?


  • 共1个答案

    匿名用户

    你问:

    我的问题是:同步会阻止它正在执行的当前线程还是当前队列?

    它会阻塞当前线程。

    在处理串行队列(例如主队列)时,如果该队列正在运行线程被阻塞的某个对象,则会阻止该队列上运行任何其他对象,直到该队列再次空闲。串行队列一次只能使用一个线程。因此,从任何串行队列向自身同步调度将导致死锁。

    但是,技术上讲,同步不会阻止队列。它会阻止当前线程。值得注意的是,在处理并发队列(如全局队列或自定义并发队列)时,该队列可以同时利用多个工作线程。因此,仅仅因为一个工作线程被阻塞,它不会阻止并发队列在另一个未被阻止的工作线程上运行另一个分派项目。因此,从并发队列同步调度到自身通常不会死锁(只要您不耗尽非常有限的工作线程池)。

    例如

    let serialQueue = DispatchQueue(label: "serial")
    
    serialQueue.async {
        serialQueue.sync {
            // will never get here; deadlock
            print("never get here")
        }
        // will never get here either, because of the above deadlock
    }
    
    let concurrentQueue = DispatchQueue(label: "concurrent", attributes: .concurrent)
    
    concurrentQueue.async {
        concurrentQueue.sync {
            // will get here as long as you don't exhaust the 64 worker threads in the relevant QoS thread pool
            print("ok")
        }
        // will get here
    }
    

    你问:

    1. 如果块线程-

    正如您在自己的代码片段中指出的那样,sync块不会执行(在串行队列场景中)。