gpt4 book ai didi

swift - DispatchQueue 是否在其自己的线程中运行?

转载 作者:行者123 更新时间:2023-12-05 02:02:01 27 4
gpt4 key购买 nike

我试图了解 DispatchQueues 的真正工作原理,我想知道假设 DispatchQueues 有自己的管理线程是否安全?例如,让我们以串行队列为例。在我的理解中——因为它是串行的,新任务只能在当前任务结束后才能开始,所以“某人”必须从队列中取出新任务并提交执行!所以,基本上看来队列必须留在它自己的线程中,该线程将分派(dispatch)存储在队列中的任务。这是正确的还是我误解了什么?

最佳答案

不,您不应该假设 DispatchQueues 有自己的托管线程,并且它不必在同一线程上执行所有任务。它只保证在前一个任务完成后接下一个任务:

Work submitted to dispatch queues executes on a pool of threads managed by the system. Except for the dispatch queue representing your app's main thread, the system makes no guarantees about which thread it uses to execute a task.

( source )

实际上,非常有可能,同一个线程将运行同一个顺序队列中的多个或所有顺序任务——前提是它们彼此靠近(及时)运行。我推测这不是纯粹的巧合,而是优化(避免上下文切换)。但这不是保证

事实上你可以做这个小实验:

let serialQueue = DispatchQueue(label: "my.serialqueue")
var incr: Int = 0

DispatchQueue.concurrentPerform(iterations: 5) { iteration in

// Rundomize time of access to serial queue
sleep(UInt32.random(in: 1...30))

// Schedule execution on serial queue
serialQueue.async {
incr += 1
print("\(iteration) \(Date().timeIntervalSince1970) incremented \(incr) on \(Thread.current)")
}
}

你会看到这样的东西:

3 1612651601.6909518 incremented 1 on <NSThread: 0x600000fa0d40>{number = 7, name = (null)}
4 1612651611.689259 incremented 2 on <NSThread: 0x600000faf280>{number = 9, name = (null)}
0 1612651612.68934 incremented 3 on <NSThread: 0x600000fb4bc0>{number = 3, name = (null)}
2 1612651617.690246 incremented 4 on <NSThread: 0x600000fb4bc0>{number = 3, name = (null)}
1 1612651622.690335 incremented 5 on <NSThread: 0x600000faf280>{number = 9, name = (null)}

迭代并发开始,但我们让它们随机休眠,以便它们在不同时间访问串行队列。结果是同一个线程不太可能执行每个任务,尽管任务执行是完全顺序的。

现在,如果您删除顶部的 sleep,导致所有迭代同时请求访问顺序队列,您很可能会看到所有任务都将在同一个线程上运行,我认为是优化,不是巧合:

4 1612651665.3658218 incremented 1 on <NSThread: 0x600003c94880>{number = 6, name = (null)}
3 1612651665.366118 incremented 2 on <NSThread: 0x600003c94880>{number = 6, name = (null)}
2 1612651665.366222 incremented 3 on <NSThread: 0x600003c94880>{number = 6, name = (null)}
0 1612651665.384039 incremented 4 on <NSThread: 0x600003c94880>{number = 6, name = (null)}
1 1612651665.3841062 incremented 5 on <NSThread: 0x600003c94880>{number = 6, name = (null)}

这是关于 iOS Concurrency "Underlying Truth" 主题的精彩读物

关于swift - DispatchQueue 是否在其自己的线程中运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66081842/

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