【问题标题】:Can tasks executed Asynchronously on Serial Queue?任务可以在串行队列上异步执行吗?
【发布时间】:2021-08-31 15:08:11
【问题描述】:

我正在尝试了解 GCD 中串行队列和并发队列的基本功能。

我们可以在并发队列上执行同步操作吗?据我所知,同步意味着一个接一个地执行任务,但是并行执行任务的并发队列怎么可能呢?这对我来说似乎很矛盾。

同理,串行队列一个接一个地执行任务,如何对串行队列进行异步操作,如何并发执行?

如果有人可以借助图片解释一下,那就很清楚了。

【问题讨论】:

    标签: asynchronous synchronization grand-central-dispatch


    【解决方案1】:

    你问:

    我们可以在并发队列上执行同步操作吗?据我所知,同步意味着一个接一个地执行任务,但是并行执行任务的并发队列怎么可能呢?

    好的,让我们在回答您的问题之前考虑一下术语:

    什么是“同步操作”?它会在该操作期间阻塞其各自的 thread。但是并发队列可以使用多个线程同时在同一个队列上执行这些单独的同步操作,每个都在自己的线程上运行。

    让我们举一个实际的例子:考虑一个同步操作,它可能是一种处理图像的算法(例如,调整图像大小或将彩色图像转换为黑白图像)。当你执行这个操作时,它一般会占用各自的线程,直到操作完成。

    因此,鉴于该示例,是的,您当然可以(而且我们经常这样做)并行执行多个并发同步操作。使用我们之前的示例,您可能有 4 个要同时处理的图像。因此,您可以实例化一个并发队列,并将这四个操作添加到该队列中,它们将被并行处理,每个都在自己的“工作线程”上。

    然后你问:

    同理,串行队列一个接一个地执行任务,如何对串行队列进行异步操作,如何并发执行?

    这在一定程度上取决于您所说的“操作”是什么意思。您是在谈论“操作队列”上的 Swift Operation(或 Objective-C NSOperation)吗?或者您是否更广泛地使用“操作”这个术语,因为它适用于 GCD 和调度队列?

    我问的原因是,在 GCD(又名“调度队列”)的世界中,您根本不会“在串行队列上执行异步操作”。您从串行队列启动异步任务,但“异步”的定义意味着当前线程不等待任务完成(这通常意味着,通常在幕后,另一个队列/线程正在做这项工作)。

    当您从串行队列启动一系列网络请求时就是一个很好的例子。隐藏在NSURLSession/URLSession 中,它有自己的队列/线程同时管理这些多个网络请求。如果您不希望这些请求同时运行,则需要采取一些技巧来采用专为并发操作而设计的 API,并使其按顺序运行,一个接一个。

    这是操作队列发挥作用的地方,因为它们确实具有自定义Operation/NSOperation 子类的概念,您可以在其中定义一个操作来包装异步任务,例如在异步任务完成之前,操作不会“完成”。它使用 KVO 在操作执行、完成等时通知队列。在这种情况下,您可以定义一个串行操作队列(即,一个具有 maxConcurrentOperationCount1 的队列) ,将一系列您自己的异步操作子类实例添加到该队列中,它可以顺序运行它们,一个接一个。但是使用异步操作的操作队列可能有点复杂。如果这确实是您想要做的,我们可以为您提供一些示例。但是,为了全面披露,这种操作队列模式现在使用频率较低,您会经常看到其他模式,例如 Combine 或新的 async-await API,以实现类似的结果。

    因此,如果不详细说明“串行队列上的异步操作”的确切含义,我们将无法回答后一个问题。给我们一个实际的例子来说明你的意思(以及你正在使用什么 API)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多