dispatch_get_global_queue behaviour

36,327

Solution 1

That depends on the machine you're running on. I suspect you're running this on your Mac, because GCD will automatically create enough threads for the specific system for jobs on the global queues. So, you probably have more than one core, so GCD is running your jobs on both the cores.

If you create your queue using dispatch_queue_create, you get a serial queue, and you are then guaranteed FIFO behaviour.

FWIW (although you shouldn't rely on this behaviour), if you run that on the iPhone, I suspect you'll see serial queue behaviour, because your iPhone is single-core. Don't rely on this though, the iPad 2 is multi-core I think!

EDIT:

Documentation for dispatch_get_global_queue: Returns a well-known global concurrent queue of a given priority level.

Solution 2

You've just illustrated why you shouldn't call methods that aren't thread-safe inside dispatch_async. If there are enough processing cores to execute more jobs, GCD will go ahead and pile work on them regardless of whether previous jobs in a given queue have returned yet. The same behaviour can be achieved in OS X 10.7 by creating your own queues with:

dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);

Obviously NSLog() can be called as often as you like without worrying about getting bad access errors or similar but if you're concerned about thread-safety or the order in which your jobs return consider using dispatch groups.

Share:
36,327
Ashish Awaghad
Author by

Ashish Awaghad

Human *ashish = [[Human alloc] initWithName:@"Ashish Awaghad" nationality:@"Indian" type:@"Developer" alsoLikes:@[@"Solving Puzzles", @"Playing Volleyball", @"Working in small setups"]]; [ashish makeAwesome]; // ! :) https://www.21.co/ashishios https://www.codementor.io/ashishios https://hackhands.com/difficultashish

Updated on November 16, 2020

Comments

  • Ashish Awaghad
    Ashish Awaghad over 3 years

    The following code:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        for (int i=0; i<100000; i++) {
            NSLog(@"HIGH 1 %d", i);
        }
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        for (int i=0; i<100000; i++) {
            NSLog(@"LOW %d", i);
        }
    });
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        for (int i=0; i<100000; i++) {
            NSLog(@"HIGH 2 %d", i);
        }
    });
    

    results in mixture of high 1, high 2 and low logs.

    How is it that it prints high1 and high2 logs simultaneously. aren't both high1 and high2 blogs on the same queue? So shouldn't high1 block finish before starting to execute high2 block?