5

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?

Puneet Sharma
  • 9,369
  • 1
  • 27
  • 33
Bhavesh
  • 1,422
  • 1
  • 12
  • 31

5 Answers5

4

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.

Nikolai Ruhe
  • 81,520
  • 17
  • 180
  • 200
3

There is only one main queue. In your first example, viewDidLoad is running on it. You then tell viewDidLoad to wait (i.e. "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.

Phillip Mills
  • 30,888
  • 4
  • 42
  • 57
  • So, You want to say that main queue will become free after call to dispatch_async() function? – Bhavesh Sep 11 '13 at 12:36
  • After `dispatch_async` the method will return rather than wait and so the main queue can be used for other things, including running your block...as long as nothing else takes control of it. – Phillip Mills Sep 11 '13 at 12:45
0

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.

Amar
  • 13,202
  • 7
  • 53
  • 71
0

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.

Puneet Sharma
  • 9,369
  • 1
  • 27
  • 33
  • You want to say that the dispatch_async() will create another thread for execution then why dispatch_async() call to the main queue still executes the block on main queue instead of creating another thread? – Bhavesh Sep 11 '13 at 12:40
  • -1 because thats not true. `dispatch_async()` on the main queue for example will still execute the block on the main thread. – JustSid Sep 11 '13 at 12:50
  • It came out bad. By another thread I wanted to say asynchronous operation. Edited to explain better. – Puneet Sharma Sep 11 '13 at 13:28
0

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

esthepiking
  • 1,647
  • 1
  • 16
  • 27
user1099178
  • 83
  • 3
  • 6