Deadlock when calling dispatch_sync() even though it's on another queue

226 views Asked by At

I am aware that calling dispatch_async in the current queue will cause a deadlock, however, experiencing a deadlock in a completely different queue:

-(void) deadlock{
    // we reach this point in the main queue
    dispatch_sync(dispatch_queue_create("lucas", 0), ^{
        NSLog(@"Doing something in the bakcgound...");
        // We reach this point in another queue, but it deadlocks!
        dispatch_sync(dispatch_get_main_queue(), ^{
            NSLog(@"Will I ever get here?????");
        });
    });
}

Any idea of what I'm doing wrong??

2

There are 2 answers

0
Sergii Martynenko Jr On

Yes, it's a deadlock. Just like you have been creating an example of one

-(void) deadlock{

    // we reach this point in the main queue
    //and so main queue waits till this task will finish
    dispatch_sync(dispatch_queue_create("lucas", 0), ^{

        //doing something in background
        //while main queue still blocked by that dispatch_sync() call
        NSLog(@"Doing something in the bakcgound...");

        // We reach this point in another queue, but it deadlocks!
        //Of cause it does!!! Main queue is still waiting till task dispatched to "lucas" queue synchronously finishes. But it can't - waits for main queue to perform this later bock synchronously
        dispatch_sync(dispatch_get_main_queue(), ^{
             NSLog(@"Will I ever get here?????");
        });
    }); 
 }
 //we reach this point only after all code written above will performed. so, in our case, this point is unreachable either way 

So, dependently on your task, you should change one of this dispatch_sync() to dispatch_async().

3
Yuchen On

Dispatch_sync is semantically equivalent to a traditional mutex lock, rather than creating a thread. Try the following, will give you: "Is main thread: 1".

dispatch_sync(dispatch_queue_create("lucas", 0), ^{

    NSLog(@"Doing something in the bakcgound...");
    NSLog(@"Is main thread: %d", [NSThread isMainThread]);

    // We reach this point in another queue, but it deadlocks!
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"Will I ever get here?????");
    });
});

What you want I think is more or less the following:

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){

    NSLog(@"Doing something in the bakcgound...");

    dispatch_async(dispatch_get_main_queue(), ^(void){
         NSLog(@"Will I ever get here?????");
    });
});