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 isNote 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.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
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.
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.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
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!