我正经历DispatchQueue障碍,并注意到sync(flags: .barrier)
和DispatchQueue.global().sync {
}
有两种方式
我了解异步屏障的用法,但与同步屏障相混淆。
我也很困惑,我想要做的任务也可以用这个来完成
DispatchQueue.global().sync(flags: .barrier) {
}
那么同步屏障的用途是什么?为什么使用它们?以及这有何不同。
{{1}}
答案 0 :(得分:4)
在分配屏障同步任务之前分配的任务(同步/异步)将首先完成。然后,屏障同步任务将被专门执行,并且由于它是同步任务,其他任务直到完成为止都不会开始。
具有屏障/非屏障同步和异步的并发队列示例。
let dispatchQueueA = DispatchQueue(label: "A", attributes: .concurrent)
dispatchQueueA.async { // Task1
for index in 0 ..< 5 {
sleep(2)
print("Task 1 - async \(index)")
}
}
dispatchQueueA.sync { // Task2
for index in 0 ..< 5 {
sleep(1)
print("Task 2 - sync without barrier \(index)")
}
}
dispatchQueueA.sync(flags: .barrier) { // Task3
// the tasks(sync, async) assigned before this block will be completed first
// then this task will execute and as it is sync task no other task will start until it finishes
for index in 0 ..< 5 {
sleep(1)
print("Task 3 - sync with barrier \(index)")
}
}
dispatchQueueA.async { // Task4
for index in 5 ..< 10 {
sleep(1)
print("Task 4 - async \(index)")
}
}
dispatchQueueA.sync { // Task5
for index in 5 ..< 10 {
sleep(1)
print("Task 5 - sync without barrier \(index)")
}
}
上述代码的输出-完成 Task1 和 Task2 后执行的 Task3(同步屏障)。完成 Task3(同步屏障)后,已启动下一个分配的任务(Task4,Task5)。
Task 2 - sync without barrier 0
Task 1 - async 0
Task 2 - sync without barrier 1
Task 2 - sync without barrier 2
Task 2 - sync without barrier 3
Task 1 - async 1
Task 2 - sync without barrier 4
Task 1 - async 2
Task 1 - async 3
Task 1 - async 4
Task 3 - sync with barrier 0
Task 3 - sync with barrier 1
Task 3 - sync with barrier 2
Task 3 - sync with barrier 3
Task 3 - sync with barrier 4
Task 5 - sync without barrier 5
Task 4 - async 5
Task 5 - sync without barrier 6
Task 4 - async 6
Task 5 - sync without barrier 7
Task 4 - async 7
Task 5 - sync without barrier 8
Task 4 - async 8
Task 5 - sync without barrier 9
Task 4 - async 9
答案 1 :(得分:3)
这里有两件事要考虑:
Sync / Asyc 确定提交队列上的程序流:使用sync()
导致提交队列上的执行被阻塞,直到任务完成为止;相反,使用async()
不会阻止。
但是,使用标志.barrier
,会影响块在提交到它们的队列中的执行方式(显然,这仅对并发队列有所不同):>
使用此标志提交的块将充当屏障:屏障之前 提交的所有其他块将完成,然后屏障块才会执行。在屏障完成后 提交的所有块都不会启动。
答案 2 :(得分:3)