Swift DispatchQueue同步与并发队列中的同步障碍

Swift DispatchQueue同步与并发队列中的同步障碍,swift,concurrency,grand-central-dispatch,shared-memory,Swift,Concurrency,Grand Central Dispatch,Shared Memory,我正在检查DispatchQueue屏障,发现有两种方法async(标志:.barrier)和sync(标志:.barrier) 我理解异步屏障的用法,但与同步屏障混淆了 我的困惑我想做的任务也可以用这个来完成 DispatchQueue.global().sync { } 那么同步屏障有什么用呢?为什么使用它们?这是多么的不同 DispatchQueue.global().sync(flags: .barrier) { } 这里有两件不同的事情要考虑: Sync/Asyc确定提交队列上

我正在检查DispatchQueue屏障,发现有两种方法
async(标志:.barrier)
sync(标志:.barrier)

我理解异步屏障的用法,但与同步屏障混淆了

我的困惑我想做的任务也可以用这个来完成

DispatchQueue.global().sync {

}
那么同步屏障有什么用呢?为什么使用它们?这是多么的不同

DispatchQueue.global().sync(flags: .barrier) {

}

这里有两件不同的事情要考虑:

Sync/Asyc确定提交队列上的程序流:使用
Sync()
会阻止提交队列上的执行,直到任务完成;相反,使用
async()
不会阻塞

但是,使用标志
.barrier
会影响块在其提交到的队列上执行的方式(显然,这只会对并发队列产生影响):

使用此标志提交的块将用作屏障:在屏障之前提交的所有其他块将完成,并且只有在完成之后屏障块才会执行。在屏障完成之前,屏障后提交的所有区块都不会启动

注意:屏障标志对全局队列没有影响。您必须创建自己的并发队列才能使用屏障块。 (感谢Rob明确指出了这一点!)

在(+1),
sync
/
async
和屏障是两个完全不同的问题。
sync
/
async
指示调用线程的行为(即它是否等待)。障碍决定了它被调度到的队列的行为(是否允许它与该队列的任何其他调度块同时运行)

不过,请注意,障碍对全局队列不起作用;它们只影响您创建的私有并发队列。关于障碍:

您指定的队列应该是您自己创建的并发队列。。。如果传递给此函数的队列是串行队列或全局并发队列之一,则此函数的行为[就好像它是在没有屏障的情况下调度的]

在分配屏障同步任务之前分配的任务(同步/异步)将首先完成。然后,屏障同步任务将以独占方式执行,由于它是一个同步任务,因此在完成之前,不会启动任何其他任务

具有屏障/非屏障同步和异步的示例并发队列。

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)")
    }
}
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

但为什么屏障不会影响全局并发队列?它们与受障碍影响的普通私有并发队列有什么不同?有什么想法吗?@HudiIlfeld全球队列共享。你不是唯一一个可能利用这些队列的人。应用程序中的其他子系统可能正在使用它们。操作系统也可能。屏障是一种阻塞操作,如果它们开始阻塞不相关的系统,可能会产生严重影响。在我看来,GCD防止一个子系统中的一点代码阻塞所有其他完全无关的子系统似乎是非常谨慎的。