当前位置: 首页 > 知识库问答 >
问题:

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

丁嘉
2023-03-14

我很困惑。

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

// 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个答案

    景宏富
    2023-03-14

    你问:

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

    它会阻塞当前线程。

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

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

    例如

    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块不会执行(在串行队列场景中)。

     类似资料:
    • 我需要一个库或我们的软件工具,可以: 1)将线程/作业/任务(任何东西--如果需要,我们可以重写代码,我们在mintue有线程对象)放入像system这样的队列中2)我们可以定义同时最多运行多少线程3)线程完成后,线程从队列中移除,这样GC就可以移除所有涉及的实体。 我正在进行大量阅读,发现ExecutorService(Executors.newFixedThreadPool(5);)但问题可能

    • 在使用TensorFlow进行异步计算时,队列是一种强大的机制。 正如TensorFlow中的其他组件一样,队列就是TensorFlow图中的节点。这是一种有状态的节点,就像变量一样:其他节点可以修改它的内容。具体来说,其他节点可以把新元素插入到队列后端(rear),也可以把队列前端(front)的元素删除。 为了感受一下队列,让我们来看一个简单的例子。我们先创建一个“先入先出”的队列(FIFOQ

    • 在使用TensorFlow进行异步计算时,队列是一种强大的机制。 正如TensorFlow中的其他组件一样,队列就是TensorFlow图中的节点。这是一种有状态的节点,就像变量一样:其他节点可以修改它的内容。具体来说,其他节点可以把新元素插入到队列后端(rear),也可以把队列前端(front)的元素删除。 为了感受一下队列,让我们来看一个简单的例子。我们先创建一个“先入先出”的队列(FIFOQ

    • 我编写了一个简单的类,我计划将其扩展为客户端套接字编程应用程序的一部分。类涉及一个BlockingQueue(我从这里复制了代码:相当于Java的BlockingQueue的C++)。当我创建了下面的包装类的一个实例后,我打算让它生成一个单独的线程,该线程只需执行BlockingQueue上阻塞的printer()函数,直到有一个或多个字符串可用,然后它只需将字符串打印到控制台窗口。在我的预期应用

    • 问题内容: 我正在尝试编写一个程序,该程序在循环中创建新线程,而不等待它们完成。据我了解,如果我在线程上使用.start(),则我的主循环应继续执行,而另一个线程将关闭并同时执行其工作 但是,一旦我的新线程启动,循环就会阻塞,直到线程完成为止。我是否误解了python中线程的工作方式,还是我正在做一些愚蠢的事情。 这是我用于创建新线程的代码。 谢谢大家 问题答案: 这将调用该函数并将其 结果 传递

    • 我正计划创建可调整队列大小的可调整线程池。我正在使用unbounded LinkedBlockingQueue和一个外部设置,该设置控制排队的消息数量。最初,my corepoolsize和maxpoolsize是相等的。现在,如果我想在运行时更新我的线程池大小,我通过一个公共设置将corepoolsize和maxpoolsize设置为不同的值。我想知道你对这种做法有什么看法。 当maxpools

    • 问题 你有一个线程队列集合,想为到来的元素轮询它们, 就跟你为一个客户端请求去轮询一个网络连接集合的方式一样。 解决方案 对于轮询问题的一个常见解决方案中有个很少有人知道的技巧,包含了一个隐藏的回路网络连接。 本质上讲其思想就是:对于每个你想要轮询的队列,你创建一对连接的套接字。 然后你在其中一个套接字上面编写代码来标识存在的数据, 另外一个套接字被传给 select() 或类似的一个轮询数据到达

    • 如果正在运行的线程少于corePoolSize线程,则执行器宁愿添加一个新线程,而不是排队。2)如果corePoolSize或更多线程正在运行,则执行器更喜欢将请求排队,而不是添加新线程。 如果请求无法排队,将创建一个新线程,除非该线程将超过maximumPoolSize,在这种情况下,任务将被拒绝。 第一种情况是可以的,但我想要的是,当核心线程被利用时,任务不需要排队(即使在有界队列的情况下,比