简体   繁体   中英

Why dispatch_sync( ) call on main queue is blocking the main queue?

I know this is not a strong question but I have to clear my mind on this concept.

I have defined myBlock as follows.

void(^myBlock)(void) = ^{
   for(int i = 0;i < 10 ; i++)
   {
       NSLog(@"%d and current queue = %@",i,[NSThread currentThread]);
   } 
};

Now In viewDidLoad method when I uses the dispatch_sync() method independently on main queue then the main queue gets blocked.

Here is the Sample.

- (void)viewDidLoad
 {
    [super viewDidLoad];
    dispatch_queue_t queue = dispatch_get_main_queue();
    dispatch_sync(queue,myBlock);
 }

But But, when I use the same dispatch_sync() function on main thread Inside a block of dispatch_async() function which is fired on concurrent queue then the main thread does not blocked.

Here is the sample.

- (void)viewDidLoad
 {
    [super viewDidLoad];
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    dispatch_async(queue,^{  

        dispatch_sync(dispatch_get_main_queue(),myBlock);
    });
 }

I am not clear why this is happening? Why main thread blocked when calling dispatch_sync() independently?

When using dispatch_sync on a serial queue (like the main queue) the current thread has to wait until the dispatched code is executed.

A dead lock occurs when a block is dispatched synchronously on from a serial queue to the same queue.

There is only one main queue. In your first example, viewDidLoad is running on it. You then tell viewDidLoad to wait (ie "sync") on something else that's going to run on the main queue. They both can't be on it at exactly the same time.

In your second example, it's the concurrent queue that's being told to wait. That's not a problem because by doing dispatch_async , viewWillLoad is giving up the main queue and making it available for your block to run.

Dispatching a block on main queue is equivalent of calling it on the main thread. Main queue executes on main thread.

Since you are dispatching using dispatch_sync this will be a blocking call as dispatch_sync ,

Submits a block object for execution on a dispatch queue and waits until that block completes.

Just need to understand this:

dispatch_sync() blocks the dispatch queue, submit the block to it and waits until the submitted block completes.

dispatch_async() submits the block for asynchronous execution on dispatch queue and returns immediately.

When you run an async task, it will create a new thread and your code in the block will be executed in that new thread. In that method you call dispatch_sync on main thread because you want to run in the main queue. Please try to understand it with this example.

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

    if ([NSThread isMainThread])
    {
        NSLog(@"Running on main Thread in dispatch_async");
    }
    else
    {
        NSLog(@"Running on another Thread in dispatch_async");
    }

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

        if ([NSThread isMainThread])
        {
            NSLog(@"Running on main Thread in dispatch_sync");
        }
        else
        {
            NSLog(@"Running on another Thread in dispatch_sync");
        }
    });

    dispatch_sync(dispatch_get_main_queue(), ^(void) {

        if ([NSThread isMainThread])
        {
            NSLog(@"Running on main Thread in dispatch_sync");
        }
        else
        {
            NSLog(@"Running on another Thread in dispatch_sync");
        }
    });

});

Output is:

Running on another Thread in dispatch_async
Running on another Thread in dispatch_sync
Running on main Thread in dispatch_sync

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM