Ios 调度队列同步并发
好吧,我已经回答了大量的问题和答案,我知道对它的理解,但是当我尝试一些代码时,我得到了一些不符合这些理论的结果 到目前为止,我的理解是:Ios 调度队列同步并发,ios,swift,grand-central-dispatch,Ios,Swift,Grand Central Dispatch,好吧,我已经回答了大量的问题和答案,我知道对它的理解,但是当我尝试一些代码时,我得到了一些不符合这些理论的结果 到目前为止,我的理解是: 同步:一旦执行块内的所有任务,控件将返回 异步:控件将在命中块后立即返回 这是看起来不错的部分。 现在是棘手的部分 串行:任务将在块内以串行方式执行。 问题1:这是否适用于区块内的任务?因为它已经在所有场景中发生。同样对于同步串行队列,在不同的块中添加任务并不重要,因为一旦完成第一个任务,控制就会返回 乙二醇- 预期输出:ABC*10,XYZ*10 这很好 现
因此,从这一点我无法理解,并发类型的串行队列的目的是什么 如果有人能给出代码示例,我将不胜感激,因为我已经知道了它的理论和工作原理。
非常感谢。要了解串行/并发队列和同步/异步方法之间的区别,以及它们是如何分配到队列的,请尝试在游戏场上播放下一个片段
import PlaygroundSupport
import Dispatch
PlaygroundPage.current.needsIndefiniteExecution = true
let q = DispatchQueue(label: "concurrect queue", qos: .background, attributes: .concurrent)
func runner0(queue: DispatchQueue) {
for _ in 1..<10 {
let result = queue.sync { ()->Int in
usleep(100)
return 0
}
DispatchQueue.main.async {
print(result, "-")
}
}
}
func runner1(queue: DispatchQueue) {
for _ in 1..<10 {
let result = queue.sync { ()->Int in
usleep(100)
return 1
}
DispatchQueue.main.async {
print("-", result)
}
}
}
let arr = [runner0, runner1]
DispatchQueue.concurrentPerform(iterations: 2) { (i) in
arr[i](q)
}
让我们通过更改队列的定义,使队列成为串行队列
let q = DispatchQueue(label: "serial queue")
并比较我们得到的结果
0 -
- 1
0 -
- 1
0 -
- 1
0 -
- 1
0 -
- 1
0 -
- 1
0 -
- 1
0 -
- 1
0 -
- 1
实际上,在您的代码中,当您在并发队列(第二个代码段)中执行任务时,您是通过sync block分派任务的,因此这将根据sync行为阻塞当前线程 “同步:一旦执行块内的所有任务,控件将返回。”
let syncConc = DispatchQueue(label:"con",attributes:.concurrent)
syncConc.sync{
for _ in 0...10{
print("XYZ")
}
for _ in 0...10{
print("ABC")
}
}
syncConc.sync{
for _ in 0...10{
print("HHH")
}
for _ in 0...10{
print("XXX")
}
}
因此,在这种情况下,首先,suncConc队列将调度第一个同步块,现在由于它是阻塞调用,下一个任务不会立即被调度,它将被调度,一旦第一个任务完成,然后它将在suncConc队列中被调度,并再次使用阻塞调用执行
现在,让我来回答你的问题
“现在,当我引入并发串行Q时,输出是相同的。因此,我的问题是,正如并发队列所说,任务将在同一时间或同时完成,它不会发生。”
是的,同步操作也可以并发执行,但只有当您在不阻塞当前线程的情况下立即分派两个调用时才可能。检查以下代码段,这两个同步任务是从不同的队列分派的,因此它将并发执行
let syncConc = DispatchQueue(label:"con",attributes:.concurrent)
DispatchQueue.global(qos: .utility).async {
syncConc.sync{
for _ in 0...10{
print("XYZ - \(Thread.current)")
}
for _ in 0...10{
print("ABC - \(Thread.current)")
}
}
}
DispatchQueue.global(qos: .userInitiated).async {
syncConc.sync{
for _ in 0...10{
print("HHH - \(Thread.current)")
}
for _ in 0...10{
print("XXX - \(Thread.current)")
}
}
}
执行代码&看看魔术所有的理论都会像预期的那样应用:)问题是你把队列类型和执行模型搞混了 有串行队列和并发队列,您可以同步或异步地向这两种类型分派任务 队列可以是:
- 串行->一次只执行一个任务
- 并发->可以同时运行多个任务
- 同步->调用方需要等待该任务返回
- 异步->调用方代码无需等待任务完成即可重新获得控制权
- 队列的串行或并发类型决定它是否可以同时执行一个或多个任务
- 同步或异步调度任务可确定调用方的代码何时恢复控制
0 -
- 1
0 -
- 1
0 -
- 1
0 -
- 1
0 -
- 1
0 -
- 1
0 -
- 1
0 -
- 1
0 -
- 1
let syncConc = DispatchQueue(label:"con",attributes:.concurrent)
syncConc.sync{
for _ in 0...10{
print("XYZ")
}
for _ in 0...10{
print("ABC")
}
}
syncConc.sync{
for _ in 0...10{
print("HHH")
}
for _ in 0...10{
print("XXX")
}
}
let syncConc = DispatchQueue(label:"con",attributes:.concurrent)
DispatchQueue.global(qos: .utility).async {
syncConc.sync{
for _ in 0...10{
print("XYZ - \(Thread.current)")
}
for _ in 0...10{
print("ABC - \(Thread.current)")
}
}
}
DispatchQueue.global(qos: .userInitiated).async {
syncConc.sync{
for _ in 0...10{
print("HHH - \(Thread.current)")
}
for _ in 0...10{
print("XXX - \(Thread.current)")
}
}
}