sal*_*qui 5 multithreading grand-central-dispatch swift
我正在使用具有QoS背景的串行队列
let serialQueue = DispatchQueue(label: "queue1", qos: DispatchQoS.background)
Run Code Online (Sandbox Code Playgroud)
分配一个作业同步,两个作业异步:
func serialTask() {
serialQueue.sync {
for i in 0..<10 {
print("", i)
}
}
serialQueue.async {
for i in 20..<30 {
print("??", i)
}
}
serialQueue.async {
for i in 101..<120 {
print("", i)
}
}
}
Run Code Online (Sandbox Code Playgroud)
所有3个作业一个接一个地执行同步,但最后两个作业是异步的.同步作业是否在串行队列中同步.
让我看看,如果我能减轻你的了担忧async对sync.
我将在我的示例中使用的一些更改:
我将使用Instruments的"兴趣点"来显示任务何时运行而不是print语句.这样我们就可以用图形方式查看行为.
我会在发送一些东西时发布一个简单的路标,我将使用一个路标范围以图形方式说明某个过程的持续时间.
我会将你的for循环改为a Thread.sleep(forTimeInterval: 1),模拟一些耗时的过程.如果你只是快速for循环,事情会发生得如此之快,以至于无法辨别线程的真实情况.
所以,考虑一下:
enum SignPostCode: UInt32 { // some custom constants that I'll reference in Instruments
case seriesOfTasks = 0
case sync = 1
case async = 2
case dispatch = 3
}
enum SignPostColor: UInt { // standard color scheme for signposts in Instruments
case blue = 0
case green = 1
case purple = 2
case orange = 3
case red = 4
}
override func viewDidLoad() {
super.viewDidLoad()
let queue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".serial")
// Because `seriesOfTasks` includes a synchronous call to something slow and we should never
// block the main thread, we will therefore start this from a global queue. It's not relevant to
// to the broader point here. You'd see the same behavior if you do this from the main thread), but
// it's best practice to never block the main thread.
DispatchQueue.global().async {
self.seriesOfTasks(on: queue)
}
}
private func seriesOfTasks(on queue: DispatchQueue) {
// flag start of `seriesOfTasks` (in blue)
kdebug_signpost_start(SignPostCode.seriesOfTasks.rawValue, 0, 0, 0, SignPostColor.blue.rawValue)
// do sync 1
kdebug_signpost(SignPostCode.dispatch.rawValue, 1, 0, 0, 0)
queue.sync {
self.oneSecondProcess(on: queue, with: .sync, arg1: 1, color: .green)
}
// do async 2
kdebug_signpost(SignPostCode.dispatch.rawValue, 2, 0, 0, 0)
queue.async {
self.oneSecondProcess(on: queue, with: .async, arg1: 2, color: .purple)
}
// do async 3
kdebug_signpost(SignPostCode.dispatch.rawValue, 3, 0, 0, 0)
queue.async {
self.oneSecondProcess(on: queue, with: .async, arg1: 3, color: .purple)
}
// flag end of `seriesOfTasks` (in blue)
kdebug_signpost_end(SignPostCode.seriesOfTasks.rawValue, 0, 0, 0, SignPostColor.blue.rawValue)
}
private func oneSecondProcess(on queue: DispatchQueue, with code: SignPostCode, arg1: UInt, color: SignPostColor) {
kdebug_signpost_start(code.rawValue, arg1, 0, 0, color.rawValue)
Thread.sleep(forTimeInterval: 1)
kdebug_signpost_end(code.rawValue, arg1, 0, 0, color.rawValue)
}
Run Code Online (Sandbox Code Playgroud)
这就像你的例子,而不是print声明,我们有kdebug声明,在乐器的"兴趣点"工具中产生以下图形时间线:
所以,你可以看到:
该seriesOfTasks功能以蓝色发出sync调度,第一个红色Ⓢ路标.
它等待sync绿色的任务在继续之前完成,此时它会发出两个后续的调度,第二个和第三个红色Ⓢ路标(它们连续发生很快,它们在图中重叠).
但是seriesOfTasks不要等待async紫色的两个任务完成.一旦完成调度这些async任务,它立即返回.
因为后台队列是串行的,所以三个调度的任务(一个sync是绿色,两个async是紫色)相互之间串行运行.
但是,如果将其更改为使用并发队列,则:
let queue = DispatchQueue(label: Bundle.main.bundleIdentifier! + ".concurrent", attributes: .concurrent)
DispatchQueue.global().async {
self.seriesOfTasks(on: queue)
}
Run Code Online (Sandbox Code Playgroud)
然后你可以看到这两个async任务现在彼此同时运行:
这一次,seriesOfTasks调度sync呼叫(等待其完成),然后,只有当sync调用完成可seriesOfTasks继续派遣两个async呼叫(在这种情况下,不等待那些派遣任务完成).
如您所见,行为async和sync行为是不同的.随着sync调用线程将等待分派任务来完成,但是async,它不会.
| 归档时间: |
|
| 查看次数: |
2315 次 |
| 最近记录: |