I want to add blocks A, B, C into global concurrent queue. Immediately after that I want to add barrier to the same queue.
I expect that A, B, C all be called in some order but when all blocks terminate the barrier will be invoked.
How can I guarantee that NO additional block will be inserted in the middle of this sequence? For example, if in some other place I deploy block X on the same queue, I do not want it to be executed before the barrier.
Can the same solution be available both on MacOS and iOS?
Barriers don’t work on global queues. Create your own custom concurrent queue. As the dispatch_barrier_async
documentation says:
The queue you specify should be a concurrent queue that you create yourself using the
dispatch_queue_create
function. If the queue you pass to this function is a serial queue or one of the global concurrent queues, this function behaves like thedispatch_async
function.
Then anything dispatched to that queue after the barrier won’t run until after the barrier. So dispatch A, B, and C. Then dispatch D with a barrier. Then dispatch X. The A, B, and C will run concurrently with respect to each other, when they’re done then D will run, and when D is done, X will run. That’s how it works, on both macOS and iOS. Just create your own custom concurrent queue.
dispatch_queue_t queue = dispatch_queue_create("com.company.app.queue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"start - A!\n");
sleep(4);
NSLog(@"end - A!\n");
});
dispatch_async(queue, ^{
NSLog(@"start - B!\n");
sleep(2);
NSLog(@"end - B!\n");
});
dispatch_async(queue, ^{
NSLog(@"start - C!\n");
sleep(3);
NSLog(@"end - C!\n");
});
dispatch_barrier_async(queue, ^{
NSLog(@"Barrier - D\n");
});
dispatch_async(queue, ^{
NSLog(@"start - X!\n");
sleep(3);
NSLog(@"end - X!\n");
});