gpt4 book ai didi

ios - 了解 dispatch_queues 和同步/异步调度

转载 作者:行者123 更新时间:2023-12-01 19:56:52 25 4
gpt4 key购买 nike

我是一名 Android 工程师,试图移植一些使用 5 个串行调度队列的 iOS 代码。我想确保我以正确的方式思考事情。

  • dispatch_sync 到 SERIAL 队列基本上是将队列用作同步队列 - 只有一个线程可以访问它,并且可以将执行的 block 视为关键区域。它立即发生在当前线程上——相当于
    get_semaphore()
    queue.pop()
    do_block()
    release_semaphore()
  • dispatch_async 到串行队列 - 在另一个线程上执行 block 并让当前线程立即返回。然而,由于它是一个串行队列,它保证一次只会执行其中一个异步线程(对 dispatch_async 的下一次调用将等到所有其他线程完成)。该 block 也可以被认为是一个关键区域,但它会发生在另一个线程上。所以与上面相同的代码,但它首先传递给一个工作线程。

  • 我是不是在其中任何一个,或者我是否正确地弄清楚了?

    最佳答案

    这感觉像是一种过于复杂的思考方式,并且该描述中有很多不完全正确的小细节。具体来说,“它立即发生在当前线程上”是不正确的。

    首先,让我们退后一步:dispatch_async 之间的区别和 dispatch_sync仅仅是当前线程是否等待它。但是,当您将某些内容分派(dispatch)到串行队列时,您应该始终想象它运行在 GCD 自己选择的单独工作线程上。是的,作为优化,有时 dispatch_sync将使用当前线程,但您无法保证这一事实。

    二、当你们讨论dispatch_sync ,你说它“立即”运行。但这绝不能保证立即生效。如果线程执行 dispatch_sync到某个串行队列,然后该线程将阻塞,直到(a)当前在该串行队列上运行的任何 block 完成; (b) 该串行队列运行和完成的任何其他排队 block ; (c) 显然,线程 A 本身分派(dispatch)的 block 运行并完成。

    现在,当您使用串行队列进行同步时,对内存中某个对象的某些线程安全访问,通常该同步过程非常快,因此等待线程通常会被阻塞一段可忽略不计的时间,因为它的调度 block (和任何先前发送的 block )来完成。但总的来说,说它会立即运行是一种误导。 (如果它总是可以立即运行,那么您就不需要队列来同步访问)。

    现在您的问题涉及“关键区域”,我假设您正在谈论一些代码,为了确保线程安全或出于类似的其他原因,必须同步这些代码。所以,当运行这段代码要同步时,唯一的问题是 dispatch_sync对比 dispatch_async是当前线程是否必须等待。例如,一种常见的模式是说可以 dispatch_async写入某个模型(因为在继续之前无需等待模型更新),但是 dispatch_sync从某个模型读取(因为您显然不想在返回读取值之前继续)。

    该同步/异步模式的进一步优化是读写器模式,其中允许并发读取但不允许并发写入。因此,您将使用并发队列 dispatch_barrier_async写入(实现类似串行的写入行为),但 dispatch_sync读取(相对于其他读取操作享受并发性能)。

    关于ios - 了解 dispatch_queues 和同步/异步调度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42034585/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com