gpt4 book ai didi

ios - dispatch_sync 和全局队列的理解

转载 作者:可可西里 更新时间:2023-11-01 03:38:37 26 4
gpt4 key购买 nike

我正在研究 GCD 机制,我有几个问题。如果我的 Material 有误,请您纠正我,我将不胜感激。

<强>1。问题) 据我所知,GCD 有 4 个具有不同优先级的全局并发队列。例如,当我们编写 DISPATCH_QUEUE_PRIORITY_HIGH 时,我们会得到其中一个队列。该队列不是空的,一些 Apple 系统进程在其上运行。因此,当我们在某些队列中添加代码块时,例如,当 n 是随机整数时,它可能是连续的 n 个任务。

现在,当我们添加代码块时,比如

dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
// Heavy calculations
});

viewDidLoad 中,所有 UI 组件都将被阻塞,直到:

  1. Apple 系统任务将完成(因为我们将任务添加到该队列的最后,应该等到其他系统任务完成)
  2. 直到我们的代码完成。

我说的对吗?我知道,我们应该在这里使用 dispatch_async,我只是想知道它是如何工作的。

<强>2。问题) 据我所知,所有的全局队列都是并发队列,这意味着它可以通过上下文切换或并行来管理任务。然而,当我们通过 dispatch_sync 到达那个队列时,我们被迫等待,直到所有的工作都完成。在这种情况下,唯一与串行队列不同的是操作顺序。例如,如果串行队列有任务 1、任务 2、任务 3 和任务 4,它会严格按顺序执行,但并发队列可以改变它的顺序,先完成轻量级操作。

那么,我的问题是,我们为什么要执行 dispatch_sync?据我了解,主线程将被阻塞,直到 dispach_sync 代码块完成。

最佳答案

GCD have 4 global concurrent queues with different priority. For example, when we write DISPATCH_QUEUE_PRIORITY_HIGH, we get one of this queues. That queues are not empty, some Apple system processes running on them.

在任何给定时间,队列可能是空的,也可能不是。没有办法知道。是的,框架可能会像您的代码一样向这些队列添加内容。

不过,队列并不运行任何东西。队列是一种数据结构。它按顺序处理任务。 GCD 管理一组工作线程,根据需要创建新线程或让它们退出。这些工作线程从队列中取出任务并执行它们。

when we add block of code, like

dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

// Heavy calculations

});

in viewDidLoad, all of UI components will be blocked, until: 1 - Apple system tasks will be completed (because we add our task last in that queue, and should wait until other system tasks finish) 2 - Until our code will complete.

顾名思义,dispatch_sync() 是同步的。这意味着它在完成要求它完成的工作(您通过的 block )之前不会返回。您是否必须等待队列中的任何其他任务取决于可用的系统资源。正如您所指出的,队列是并发的,因此可以从中提取任务以同时运行。如果有足够的空闲 CPU 核心,GCD 可能会启动足够的工作线程来同时运行队列中的所有任务。因此,您的任务不必等待其他任务完成,它只需要等待那些任务已经开始(从队列的头部弹出)并且有一个备用工作线程可用。

如果所有系统资源(如 CPU 内核)都很忙,您只需等待其他任务完成。

As far as i know, all of global queues are concurrent queues, which mean, that it could manage tasks either through context switch or parallelism. However, when we get to that queue through dispatch_sync, we forced to wait, when all of work will be done.

不,这是错误的,正如我上面所解释的。您知道在 dispatch_sync() 返回之前必须完成的唯一一件事就是您使用它提交的一项任务。它不必等待该队列上的任何其他任务,除非所有 CPU 内核都忙。

The only thing that is different from serial queues in that case, is order of operations. For example, if serial queue have task 1, task 2, task 3 and task 4, it will do this strictly in order, but concurrent queue could change it order, to complete light-weight operations first.

没有。并发队列严格按顺序开始操作,就像串行队列一样。只是在当前操作(如果有的话)完成之前,串行队列不会启动另一个操作。全局并发队列将允许其所有操作同时启动和运行,直到可用资源为止。队列无法知道操作是否轻量级。

So, my questions is, why should we ever do dispatch_sync? In my understanding, main thread will be blocked until dispach_sync code block will finish.

并发和同步行为是两个不同的概念。同步与异步决定了调用者的行为。它确定在工作完成之前是否允许调用者继续。

并发与串行决定提交的任务如何运行。并发队列允许任务彼此并发运行。串行队列一次只允许它的一个任务运行。

从主线程调用 dispatch_sync() 是有意义的,但您必须小心。例如,当使用串行队列同步访问由多个线程共享的数据结构时,这可能是必要的。一般规则是您需要避免长时间阻塞主线程。如果您有充分的理由相信它会在很短的时间内用户无法察觉,则可以阻止它。

您绝对不想在主线程中使用 dispatch_sync() 进行“繁重的计算”,正如您所说的那样。

一般来说,当您需要在继续之前完成任务时,您可以使用 dispatch_sync()。通常,您可以重组代码以改为使用 dispatch_async() 并将后续代码作为后续步骤(或完成处理程序)放入任务中。但您不能总是那样做。

关于ios - dispatch_sync 和全局队列的理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31361489/

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