如果我在 dispatch_async 块中有一个 dispatch_sync 调用,然后是第二个调度调用,那么第二个调用是同步还是异步有关系吗?

If I have a dispatch_sync call followed by a second dispatch call within a dispatch_async block, does it matter if that second call is sync or async?

此代码适用于非常标准的情况,在这种情况下,我让我的数据模型执行一些可能较慢的数据检索,并且我想在数据检索完成后用数据更新我的视图。

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

dispatch_async(queue, ^{
    dispatch_sync(queue, ^{
        //get a bunch of data
    }
    dispatch_sync(dispatch_get_main_queue(), ^{
        [viewcontroller tellViewToReloadData];
    }
}

我的问题是,如果第二个 dispatch_sync 变成 dispatch_async 会有很大的不同吗?

这是我对上面代码发生的事情的理解(我也以此为契机来衡量我对这个整体主题的理解):

  1. 外部dispatch_async立即returns,并且带有两个调度调用的块被放入并发队列。

  2. 在某个时候,外部异步块将在某个随机线程上执行,此时第一个 dispatch_sync 被调用,它的块被放入并发队列。

  3. 在某些时候,内部第一个同步块将在某个随机线程上执行我所有的数据收集操作,只有当它们全部完成时,第一个 dispatch_sync return,第二个 dispatch_sync 被调用。

  4. 第二个 dispatch_sync 被调用,包含更新视图代码的块被放入主队列。在某个时候这个块执行并且视图得到更新,第二个 dispatch_sync returns.

  5. 外部块现在已完成执行,因此并发队列可以自由地将任务推送到正在执行外部块的线程。

现在,我的理解是,如果第二个 dispatch_sync 改为 dispatch_async 调用,唯一的变化是执行外部块的线程被占用的时间稍微短一些,因为它不必等待主队列中的块完成执行。这个对吗?通过这种推理,第二个 dispatch_sync 似乎稍微好一点 dispatch_async 只是因为某些线程将被占用(可能微不足道)更短的时间,但实际上这并不重要。

  1. 第一次同步毫无意义 – 你已经在 queue.

    dispatch_async(queue, ^{
        //get a bunch of data
        dispatch_sync(dispatch_get_main_queue(), ^{
            [viewcontroller tellViewToReloadData];
        });
    });
    
  2. sync 只是 async 等待原语,就好像它是:

    dispatch_semaphore_t s = dispatch_semaphore_create(0);
    
    dispatch_async(queue, ^{
        [viewcontroller tellViewToReloadData];
        dispatch_semaphore_signal(s);
    });
    
    dispatch_semaphore_wait(s, DISPATCH_TIME_FOREVER);
    

Now, my understanding is that if that second dispatch_sync was instead a dispatch_async call, the only change is that the thread executing the outer block is occupied for a slightly shorter amount of time because it doesn't have to wait for the block in the main queue to finish executing. Is this correct?

是的。

By this reasoning it seems slightly better for the second dispatch_sync to be dispatch_async just because some thread will be occupied for a (probably trivially) shorter amount of time, but effectively it doesn't really matter.

可能许多线程被卡住等待主线程完成处于压力负载下的情况下很重要。然后系统将需要产生更多的 pthreads 以继续有效地执行其他并发任务并随后关闭过多的线程。不知道这是否适用,但如果您不需要结果,显然无需等待。