7

我知道你可能会觉得这是一个奇怪的问题,但我只是在学习 GCD,我想完全理解它的所有方面。所以这里是:

是否有任何理由在当前队列上调度任务同步?

例如:

    dispatch_queue_t concurrentQueue = dispatch_get_global_queue(...);
    dispatch_async(concurrentQueue, ^{
       //this is work task 0

       //first do something here, then suddenly:

       dispatch_sync(concurrentQueue, ^{
               //work task 1
       });

       //continue work task 0
    });

我明白一件事:如果concurrentQueue我不使用串行队列,那么我会在该串行队列上陷入死锁,因为work task 1在完成之前无法启动work task 0(因为保证执行顺序的串行队列),同时work task 0不能继续执行,因为它等待 SYNC dispath 函数返回(如果我错了,请纠正我,这会让我成为一个完全的菜鸟)。

所以回到最初的想法,上面的代码和相同的代码之间有什么区别,而不是调用dispatch_sync函数,我只是work task 1直接编写代码?

4

2 回答 2

7

不,我想不出任何理由让dispatch_sync你一直在同一个并发队列上。如果你这样做,GCD 将立即在同一个线程上直接调用你的块,就像你直接调用它一样。(我检查过。)正如您所指出的,在串行队列上执行此操作会使您陷入僵局。

于 2013-10-04T12:42:31.677 回答
3

假设所有示例都使用此队列:

dispatch_queue_t queue = dispatch_queue_create(“com.somecompany.queue”, nil);

情况 1 - 好的

dispatch_async(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_async(queue, ^{
        NSLog(@"Situation 1");
    });
});

情况 2 - 不行!僵局!

dispatch_sync(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_sync(queue, ^{
        NSLog(@"Situation 2”); // NOT REACHED!  DEADLOCK!
    });
});

情况 3 - 不行!僵局!

dispatch_async(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_sync(queue, ^{
        NSLog(@"Situation 3"); // NOT REACHED!  DEADLOCK!
    });
});

情况 4 - 好的

dispatch_sync(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_async(queue, ^{
        NSLog(@"Situation 4");
    });
});

基本上 dispatch_sync 不喜欢在里面。

只有 dispatch_asyncs 可以进去。

于 2015-09-29T22:12:23.460 回答