Bogdan Alexandru
Bogdan Alexandru

Reputation: 5542

Sync dispatch on current queue

I know you might find this an odd question, but I'm just learning GCD and I want to fully understand all its aspects. So here it is:

Is there ever any reason to dispatch a task SYNC on the CURRENT QUEUE?

For example:

    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(...);
    dispatch_async(concurrentQueue, ^{
       //this is work task 0

       //first do something here, then suddenly:

       dispatch_sync(concurrentQueue, ^{
               //work task 1
       });

       //continue work task 0
    });

I understand one thing: if instead of concurrentQueue I use a serial queue, then I get a deadlock on that serial queue, because work task 1 cannot start until the work task 0 is finished (because of the serial queue that guarantees order of execution), and in the same time work task 0 cannot continue its execution because it waits for the SYNC dispath function to return (please correct me if I'm wrong, that would make me a total noob).

So coming back to the original idea, is there any difference whatsoever between the code above and the same code where instead of calling the dispatch_sync function I simply write work task 1 code directly?

Upvotes: 7

Views: 1857

Answers (2)

TenaciousJay
TenaciousJay

Reputation: 6870

Assume this queue for all examples:

dispatch_queue_t queue = dispatch_queue_create(“com.somecompany.queue”, nil);

Situation 1 - OK

dispatch_async(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_async(queue, ^{
        NSLog(@"Situation 1");
    });
});

Situation 2 - Not OK! Deadlock!

dispatch_sync(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_sync(queue, ^{
        NSLog(@"Situation 2”); // NOT REACHED!  DEADLOCK!
    });
});

Situation 3 - Not OK! Deadlock!

dispatch_async(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_sync(queue, ^{
        NSLog(@"Situation 3"); // NOT REACHED!  DEADLOCK!
    });
});

Situation 4 - OK

dispatch_sync(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_async(queue, ^{
        NSLog(@"Situation 4");
    });
});

Basically dispatch_sync does not like to be on the inside.

Only dispatch_asyncs can go inside.

Upvotes: 3

ipmcc
ipmcc

Reputation: 29886

No. I can't think of a reason to ever dispatch_sync on the same concurrent queue you're already on. If you do that, GCD will just immediately invoke your block, in-line, on the same thread, as if you had called it directly. (I checked.) And as you pointed out, doing that on a serial queue will deadlock you.

Upvotes: 7

Related Questions