如果在串行DispatchQueue中触发上下文切换会发生什么?

时间:2017-10-03 19:12:30

标签: swift multithreading grand-central-dispatch swift-playground

原则上,序列DispatchQueue将一个接一个地执行提交的任务。但是如果在一个任务中触发上下文切换(比如调用sleep)会怎样?队列是否立即执行下一个任务,或等待当前任务完成?

对于此代码:

q.async {
    print("IN 1")
    var i = 1
    while i < 10 {
     Thread.sleep(forTimeInterval: 0.1)
     i += 1
    }
    print("OUT of 1")
}

q.async {
    print("IN 2")
}

结果是:

// IN 1 -> OUT of 1 -> IN 2 ?
// or IN 1 -> IN 2 -> OUT of 1 ?

我尝试在游乐场中运行代码,但似乎sleep(和Thread.sleep)在Playground中无效。

2 个答案:

答案 0 :(得分:4)

在前一个完成之前,串行队列不会开始执行下一个块。上下文切换不会影响这一点。如果在提交到串行队列的块中调用sleep,则会阻塞队列,直到睡眠结束并且块可以继续执行。因此,您的结果将是IN 1 -> OUT of 1 -> IN 2

请注意,一般情况下,您不希望在提交到队列的块中阻塞事物(如sleep),因为这会阻塞整个线程,使其无法用于libdispatch以用于其他工作。 libdispatch将根据需要启动新线程以继续工作,但是它将产生多少新线程的限制。

答案 1 :(得分:0)

  

原则上,串行DispatchQueue将一个接一个地执行提交的任务。但是,如果在一个任务中触发上下文切换(例如,调用睡眠)会怎么样?队列是否立即执行下一个任务,或等待当前任务完成?

串行队列不是&#34; serial&#34;只是因为它的任务是连续提交的(事实上,大多数任务通常是在并行队列中),但是因为任务保证按照提交的顺序一个接一个地完成。

Thread.sleep在游戏场上工作正常,但你的游乐场正在提前终止执行。当控制流到达页面末尾时,Playground的执行终止。所以这样的异步任务只有在控制流到达页面末尾时才会执行,这是不太可能的。

为了让游乐场无限期地执行(直到手动终止),请使用:

import PlaygroundSupport
PlaygroundPage.current.needsIndefiniteExecution = true