swift 3中调度队列的优先级

Posted

技术标签:

【中文标题】swift 3中调度队列的优先级【英文标题】:priority of Dispatch Queues in swift 3 【发布时间】:2017-03-26 06:36:53 【问题描述】:

我已经阅读了关于GCD and Dispatch Queue in Swift 3的教程

但是对于同步执行和异步执行以及主队列和后台队列的顺序,我真的很困惑。

我知道,如果我们使用 sync,那么如果我们使用 async,我们会在宝贵的一个之后执行它们strong> 那么我们可以使用 QoS 来设置它们的优先级,但是这种情况呢?

func queuesWithQoS() 
    let queue1 = DispatchQueue(label: "com.appcoda.myqueue1")
    let queue2 = DispatchQueue(label: "com.appcoda.myqueue2")

    for i in 1000..<1005 
                print(i)
    


    queue1.async 
        for i in 0..<5
            print(i)
        
    

    queue2.sync 
        for i in 100..<105
            print( i)
        
    

结果表明我们忽略了异步执行。我知道 queue2 应该在 queue1 之前完成,因为它是同步执行,但是为什么我们忽略异步执行和 async、sync 和所谓的主队列之间的实际区别是什么?

【问题讨论】:

【参考方案1】:

你说:

结果表明我们忽略了异步执行。 ...

不,这只是意味着您没有给异步调度的代码足够的时间来开始。

我知道 queue2 应该在 queue1 之前完成,因为它是同步执行的......

首先,queue2 可能不会在 queue1 之前完成。它只是碰巧。让 queue2 做一些慢得多的事情(例如循环几千次迭代,而不是仅仅五次),你会看到 queue1 实际上可以相对于 queue2 上的内容同时运行。只需几毫秒即可开始,您非常简单的 queue2 上的内容在 queue1 上的内容有机会开始之前完成。

其次,这种行为在技术上不是因为它是同步执行的。只是异步需要几毫秒才能让它在某个工作线程上运行,而同步调用由于我不会让你厌烦的优化而启动得更快。

但是为什么我们忽略异步执行...

我们不会“忽略”它。只需几毫秒即可开始。

async、sync 和所谓的主队列之间的实际区别是什么?

“异步”仅仅意味着当前线程可以继续运行,而不是等待分派的代码在其他线程上运行。 “同步”意味着当前线程应该等待分派的代码完成。

“主线程”是一个不同的主题,它只是指为驱动 UI 而创建的主线程。实际上,主线程是运行大部分代码的地方,基本上运行所有内容,除了您手动分派到某个后台队列(或为您分派的代码,例如URLSession 完成处理程序)之外的所有内容。

【讨论】:

【参考方案2】:

syncasync 与同一个线程/队列相关。要查看差异,请运行以下代码:

func queuesWithQoS() 
    let queue1 = DispatchQueue(label: "com.appcoda.myqueue1")

    queue1.async 
        for i in 0..<5
            print(i)
        
    
    print("finished")

    queue1.sync 
        for i in 0..<5
            print(i)
        
    
    print("finished")

主队列是运行整个用户界面 (UI) 的线程。

【讨论】:

所以你的意思是如果我们在不同的线程中比较异步和同步是没有意义的?而且我发现如果我多次运行它,我会得到不同的结果 是的,我就是这个意思。而且您在第一个循环中只会得到不同的结果,因为async 范围内的代码最终会执行并且完全独立于"finished" 行。第二个循环在第一个循环之后执行,因为两个循环都是在同一个队列上按 FIFO(先进先出)调度的。【参考方案3】:

首先,对于代码执行,我更喜欢使用“延迟”一词而不是“忽略”,因为您问题中的所有代码都已执行。

QoS 是enum,第一个类表示最高优先级,最后一个表示最低优先级,当您不指定任何优先级时,您有一个默认优先级的队列 并且默认在中间:

用户交互 用户发起 默认 实用程序 背景 未指定

也就是说,您有两个同步 for-in 循环和一个异步,其中优先级取决于循环的位置和代码中的队列类型(同步/异步)因为这里我们有 3 个不同的队列(按照关于您的 link 的说明,queuesWithQoS() 可以在 viewDidAppear 中启动,所以我们可以假设它在主队列中)

代码显示了两个具有默认优先级的队列的创建,因此执行顺序为:

    主队列中有 1000.. 具有默认优先级的同步 queue2 具有默认优先级的异步 queue1(不忽略,只是延迟)

主队列在执行所有 UI 指令时始终具有最高优先级。

【讨论】:

是的,由于queue1的默认优先级与queue2相同,为什么queue2执行后延迟了 只是因为queue1是异步队列,queue2是同步的,位置不优先于类型(sync/async)

以上是关于swift 3中调度队列的优先级的主要内容,如果未能解决你的问题,请参考以下文章

RTOS训练营任务调度(续)任务礼让调度总结队列和晚课提问

RTOS训练营任务调度(续)任务礼让调度总结队列和晚课提问

RTOS训练营任务调度(续)任务礼让调度总结队列和晚课提问

cpu调度

Linux 线程调度与优先级

[OS-Linux]详解Linux的进程2(进程的优先级,环境变量,程序地址空间,进程地址空间,进程调度队列)