【问题标题】:are asynchronous tasks on main thread same as synchronous tasks?主线程上的异步任务与同步任务相同吗?
【发布时间】:2020-04-13 00:12:40
【问题描述】:

我知道这两种的区别。

对于异步任务,下一个任务将在当前任务开始之后运行,这意味着如果有可用的线程,任务将被分派到多个线程。
对于同步任务,下一个任务将在当前任务完成后运行。

主线程只有一个线程,如何运行异步任务?

这让我很困惑。
提前致谢。

【问题讨论】:

标签: ios swift grand-central-dispatch


【解决方案1】:

您对异步和同步的定义不太正确。

在 Grand Central Dispatch 中,您考虑的是 队列,而不是 线程。队列要么是串行调度队列,要么是并发调度队列。

串行调度队列一次可以运行一个任务,并且任务一个接一个地调度(串行)。

并发调度队列可以在多个线程上同时运行多个任务。

任务在线程上执行,Grand Central Dispatch 负责为您分配任务给线程。

主队列是一个特殊的串行调度队列,它只将任务分配给主线程。其他队列可以将任务分配给任何可用线程,包括主线程。

现在,对于同步调度和异步调度,区别在于调度是阻塞当前线程直到调度的任务完成(同步)还是将任务排队而不阻塞当前线程(异步)。

当您异步分派到主队列时,您提供了一个工作单元,Grand Central Dispatch 将在未来某个时间分配给主线程,但您的代码会继续执行,而无需等待该分派项目完成。

您可以在主队列上运行时非常高兴地将异步任务分派到主队列,因为分派的任务将在主队列准备好执行任务时稍后执行。

你不能做的是将同步分派到主队列主队列(或更一般地说,从同一个队列同步分派到任何串行调度队列) 因为您将创建一个死锁。

分派同步阻塞当前线程/队列,直到分派项目完成。在串行调度队列上,调度项目无法执行,因为调度队列被阻塞。

【讨论】:

  • "其他队列可以将任务分配给任何可用线程,包括主线程。"这是不正确的(除了串行调度来自主线程)。调度到后台队列通常是一种让长时间运行的任务脱离主线程的方法。如果其中一个队列可以在主线程上运行这样的任务,它将锁定 UI。否则,很好的答案。 +1
  • “除了代表应用主线程的调度队列,系统不保证它使用哪个线程来执行任务。”。主队列以外的队列可以使用主线程,它仅用于异步分派的工作项。使用主队列保证该块将使用主线程。
  • 呃,我之前的评论中的意思是“同步从主线程调度”(不是串行的)。但是,实际上,这是另一个队列使用主线程的唯一方法。如果其他队列可以使用主线程从另一个线程调度或从主线程异步调度,它将破坏一切。
【解决方案2】:

对于异步任务,下一个任务将在当前任务开始之后运行,这意味着如果有可用线程,任务将被分派到多个线程。

不完全是。异步分派仅意味着当前线程将不会等待分派的代码完成。它与目标队列是串行的还是并发的完全无关。

对于同步任务,下一个任务将在当前任务完成后运行。

同样,不完全是。同步分派只意味着当前线程等待分派的代码完成执行。

分派的代码是否与之前分派到该队列的其他项目同时运行取决于队列类型(即串行或并发),而不是我们是同步还是异步分派。

主线程只有一个线程,如何运行异步任务?

现在可能很明显,“异步”与“同步”并不是被分派任务的特征,而只是决定了您从中分派的线程是否应该等待。

因此,考虑一些将代码异步分派回主线程的代码:

let task = URLSession.dataTask(with: request) { data, _, _ in
    let results = ...                 // on `URLSession` background serial queue, only populate local variables
    DispatchQueue.main.async {
        self.objects = results        // dispatch model updates back to main queue
        self.tableView.reloadData()   // also update UI from main queue
    }
}
task.resume()

在上面的示例中,我们将模型和 UI 更新分派到主队列,因为我们位于 URLSession 后台队列(恰好也是一个串行队列)。我们异步调度它,因为URLSession 的串行队列没有理由等待调度代码完成。我们本可以同步调度它,但我们为什么要费心阻塞URLSession队列,即使只是多出几毫秒。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-06
    • 1970-01-01
    • 1970-01-01
    • 2015-09-14
    • 1970-01-01
    • 1970-01-01
    • 2018-07-01
    • 2016-09-20
    相关资源
    最近更新 更多