1

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??

rmaddy
  • 314,917
  • 42
  • 532
  • 579
cfischer
  • 24,452
  • 37
  • 131
  • 214

2 Answers2

2

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().

Sergii Martynenko Jr
  • 1,407
  • 1
  • 9
  • 18
1

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?????");
    });
});
Community
  • 1
  • 1
Yuchen
  • 30,852
  • 26
  • 164
  • 234
  • So even though I call dispatch_queue_create("lucas", 0) it doesn't create a new queue??!! This is weird. – cfischer Jun 18 '15 at 12:32
  • 1
    It does. But that doesn't mean that this queue won't run on a main NSThread. When one creates a queue, he is not provided with any info about a thread, on which tasks from that queue will run – Sergii Martynenko Jr Jun 18 '15 at 12:34
  • 1
    @cfisher, I think you confuse the queue and the thread here. You can use `dispatch_async` (see my edits for more detail) to create a thread, or use [NSObject to spawn a thread](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html#//apple_ref/doc/uid/10000057i-CH15-SW13). – Yuchen Jun 18 '15 at 14:56