为什么在主队列上调用dispatch_sync()会阻塞主队列?

时间:2013-09-11 12:12:31

标签: iphone ios multithreading

我知道这不是一个强烈的问题,但我必须清楚这个概念。

我已将myBlock定义如下。

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

现在在viewDidLoad方法中,当我在主队列上独立使用dispatch_sync()方法时,主队列被阻止。

以下是样本。

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

但是,当我在主线程上使用相同的dispatch_sync()函数时,在并发队列中触发的dispatch_async()函数块中,主线程不会被阻塞。

以下是样本。

- (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);
    });
 }

我不清楚为什么会这样?独立调用dispatch_sync()时为什么主线程被阻止?

5 个答案:

答案 0 :(得分:4)

在串行队列(如主队列)上使用dispatch_sync时,当前线程必须等到执行调度的代码。

当一个块从一个串行队列同步调度到同一个队列时发生死锁。

答案 1 :(得分:3)

只有一个主队列。在您的第一个示例中,viewDidLoad正在运行。然后告诉viewDidLoad等待(即“同步”)其他将要在主队列上运行的东西。它们都不能在同一时间出现在它上面。

在你的第二个例子中,它是被告知等待的并发队列。这不是问题,因为通过执行dispatch_asyncviewWillLoad放弃主队列并使其可用于您的块运行。

答案 2 :(得分:0)

在主队列上调度块相当于在主线程上调用它。主队列在主线程上执行。

由于您使用dispatch_sync进行调度,因此dispatch_sync会阻止此呼叫,

  

提交一个块对象以便在调度队列上执行,并等待该块完成。

答案 3 :(得分:0)

只需了解这一点:

  

dispatch_sync()阻止调度队列,将块提交给它   等待提交的块完成。

     

dispatch_async()在调度队列上提交异步执行块并立即返回。

答案 4 :(得分:0)

当您运行异步任务时,它将创建一个新线程,并且该块中的代码将在该新线程中执行。在该方法中,您在主线程上调用dispatch_sync,因为您想在主队列中运行。请尝试通过此示例来理解它。

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");
        }
    });

});

输出是:

在dispatch_async中的另一个线程上运行
 在dispatch_sync中的另一个线程上运行
 在dispatch_sync中的主线程上运行