DispatchQueue sync vs sync barrier in concurrent queue

Viewed 11989

I was going through DispatchQueue barrier and noticed both there are two ways async(flags: .barrier) and sync(flags: .barrier)

I understood the use of the async barrier but confused with the sync barrier.

My confusion the task I want to do can be performed with this also

DispatchQueue.global().sync {

}

then what is the use of sync barrier? Why they are used? and how different in this.

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

}
3 Answers

There are two different things to consider here:

Sync/Asyc determins the program flow on the submitting queue: Using sync() causes the execution on the submitting queue to block until the task has completed; in contrast, using async() won't block.

Using the flag .barrier, however, affects the way the blocks are executed on the queue they were submitted to (obviously, this only makes a difference on concurrent queues):

A block submitted with this flag will act as a barrier: all other blocks that were submitted before the barrier will finish and only then the barrier block will execute. All blocks submitted after the barrier will not start until the barrier has finished.

Note: the barrier flag will have no effect on global queues. You must create your own concurrent queue in order to be able to use barrier blocks. (Thanks to Rob for clearly pointing that out!)

At Lutz says (+1), sync/async and barriers are two completely different issues. The sync/async dictates the behavior of the calling thread (i.e. does it wait or not). Barriers dictate the behavior of the queue to which it it was dispatched (whether it’s allowed to run concurrently with any other dispatched blocks to that queue).

Note, though, that barriers do not work on global queues; they only affect private concurrent queues that you created. As the docs say about barriers:

The queue you specify should be a concurrent queue that you create yourself... If the queue you pass to this function is a serial queue or one of the global concurrent queues, this function behaves [as if it were dispatched without the barrier].

The tasks(sync/async) assigned before a barrier sync task has been assigned, will be completed first. Then the barrier sync task will be executed exclusively and as it is a sync task no other task will start until it finishes.

Example of a sample concurrent queue with barrier/ non-barrier sync and 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)")
    }
}

Output of the above code - Task3(sync barrier) executed after Task1 and Task2 have been completed. After completing Task3(sync barrier), next assigned tasks(Task4,Task5) have been started.

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
Related