Use of dispatch_barrier_async and dispatch_barrier_sync

First of all, the literal translation of barrier is the meaning of barrier, fence and demarcation line.

So you can intuitively think of this use and setup barriers in GCD use! uuuuuuuuuuu

For example, the first three parts of the task, the second part of the implementation after the first part, the third part of the implementation after the second part, so you can see the second part as an obstacle!

Of course, you can also use dispatch_group, but it's simpler and more intuitive to use barrier here!

Code directly

dispatch_queue_t queue = dispatch_queue_create("thread", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        sleep(3);
        NSLog(@"test1");
    });
    dispatch_async(queue, ^{
        NSLog(@"test2");
    });
    dispatch_sync(queue, ^{
        NSLog(@"test3");
    });
    dispatch_barrier_sync(queue, ^{	/// The demarcation line is synchronous here, please note.
        sleep(1);
        for (int i = 0; i<50; i++) {
            if (i == 10 ) {
                NSLog(@"point1");
            }else if(i == 20){
                NSLog(@"point2");
            }else if(i == 40){
                NSLog(@"point3");
            }
        }
    });
    NSLog(@"hello");
    dispatch_async(queue, ^{
        NSLog(@"test4");
    });
    NSLog(@"world");
    dispatch_async(queue, ^{
        NSLog(@"test5");
    });
    dispatch_async(queue, ^{
        NSLog(@"test6");
    });
The output at this time is
2017-03-10 12:32:23.797 testAttacment[30799:15814267] test2
2017-03-10 12:32:23.797 testAttacment[30799:15814173] test3
2017-03-10 12:32:26.798 testAttacment[30799:15814268] test1
2017-03-10 12:32:27.871 testAttacment[30799:15814173] point1
2017-03-10 12:32:27.872 testAttacment[30799:15814173] point2
2017-03-10 12:32:27.873 testAttacment[30799:15814173] point3
2017-03-10 12:32:27.873 testAttacment[30799:15814173] hello
2017-03-10 12:32:27.874 testAttacment[30799:15814173] world
2017-03-10 12:32:27.874 testAttacment[30799:15814268] test4
2017-03-10 12:32:27.874 testAttacment[30799:15814267] test5
2017-03-10 12:32:27.875 testAttacment[30799:15814268] test6
Note that I have delays in both test1 and barrier, but I still do the first three tasks, then the barrier, and then the next three tasks. Please pay attention to the location of hello and world.

It can be explained that the three asynchronous threads behind the hello and world roots are processed according to normal multithreading.

Then just change the barrier to asynchronous, and the output becomes asynchronous.

2017-03-10 12:36:49.042 testAttacment[31122:15818282] test3
2017-03-10 12:36:49.042 testAttacment[31122:15818283] test2
2017-03-10 12:36:49.043 testAttacment[31122:15818226] hello
2017-03-10 12:36:49.047 testAttacment[31122:15818226] world
2017-03-10 12:36:52.043 testAttacment[31122:15818287] test1
2017-03-10 12:36:53.118 testAttacment[31122:15818287] point1
2017-03-10 12:36:53.118 testAttacment[31122:15818287] point2
2017-03-10 12:36:53.119 testAttacment[31122:15818287] point3
2017-03-10 12:36:53.119 testAttacment[31122:15818287] test4
2017-03-10 12:36:53.119 testAttacment[31122:15818282] test5
2017-03-10 12:36:53.119 testAttacment[31122:15818283] test6
At this point, you can see that the location of hello and world has changed, even before test1, but the order of execution is to perform the first three tasks, then the obstacle tasks, and finally the last three tasks.

This shows that asynchronous obstacle tasks will only set obstacles to tasks in the queue without blocking the code of the main thread behind.

The queue created above is a concurrent queue, and the effect of the serial queue is the same.

So it can be concluded that:

dispatch_barrier_sync(queue,void(^block)()) executes all the task blocks added before barrier in queue, then executes the block of barrier task, and then executes the task blocks added after barrier.

dispatch_barrier_async(queue,void(^block)()) adds the task block added before the barrier in queue only to add no execution, continues to add the barrier block, and then adds the block after the barrier, without affecting the execution of the code in the main thread (or the thread that operates the added task)!

All in all, dispatch_barrier_async is used for sequential execution of tasks!

Posted by almystersv on Sat, 15 Dec 2018 10:00:03 -0800