Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/93.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 当前队列上的同步调度_Ios_Multithreading_Concurrency_Grand Central Dispatch - Fatal编程技术网

Ios 当前队列上的同步调度

Ios 当前队列上的同步调度,ios,multithreading,concurrency,grand-central-dispatch,Ios,Multithreading,Concurrency,Grand Central Dispatch,我知道你可能会觉得这是一个奇怪的问题,但我只是在学习GCD,我想完全理解它的所有方面。这就是: 是否有任何理由在当前队列上调度任务同步 例如: dispatch_queue_t concurrentQueue = dispatch_get_global_queue(...); dispatch_async(concurrentQueue, ^{ //this is work task 0 //first do something here, then

我知道你可能会觉得这是一个奇怪的问题,但我只是在学习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
而是串行队列,那么我会在该串行队列上出现死锁,因为
工作任务1
工作任务0
完成之前无法启动(因为串行队列保证了执行顺序),同时,
工作任务0
无法继续执行,因为它等待SYNC dispath函数返回(如果我错了,请纠正我,这将使我成为一个彻头彻尾的noob)


回到最初的想法,上面的代码和同一个代码之间有什么区别吗?我没有调用
dispatch\u sync
函数,而是直接编写
work task 1
代码?

没有。我想不出任何理由在您已经在的同一个并发队列上执行
dispatch\u sync
。如果您这样做,GCD将立即在同一线程上在线调用您的块,就像您直接调用它一样。(我选中了。)正如您所指出的,在串行队列上这样做会使您死锁。

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

dispatch\u queue\u t queue=dispatch\u queue\u create(“com.somecompany.queue”,nil)

情况1-正常

dispatch_async(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_async(queue, ^{
        NSLog(@"Situation 1");
    });
});
dispatch_sync(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_async(queue, ^{
        NSLog(@"Situation 4");
    });
});
情况2-不正常!死锁

dispatch_sync(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_sync(queue, ^{
        NSLog(@"Situation 2”); // NOT REACHED!  DEADLOCK!
    });
});
dispatch_async(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_sync(queue, ^{
        NSLog(@"Situation 3"); // NOT REACHED!  DEADLOCK!
    });
});
情况3-不正常!死锁

dispatch_sync(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_sync(queue, ^{
        NSLog(@"Situation 2”); // NOT REACHED!  DEADLOCK!
    });
});
dispatch_async(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_sync(queue, ^{
        NSLog(@"Situation 3"); // NOT REACHED!  DEADLOCK!
    });
});
情况4-正常

dispatch_async(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_async(queue, ^{
        NSLog(@"Situation 1");
    });
});
dispatch_sync(queue, ^{
    [self goDoSomethingLongAndInvolved];
    dispatch_async(queue, ^{
        NSLog(@"Situation 4");
    });
});
基本上,dispatch_sync不喜欢位于内部


只有dispatch\u async可以进入内部。

?唯一的问题是提出一个现实的场景,其中队列是并发的。问题是:调度同步到同一队列是多余的吗?。您的问题似乎是,向可能与当前队列不同的并发队列分配_sync是否有意义?。是的,如果您希望下一行代码发生在dispatch\u sync代码之后。一个现实的场景是:一个复杂的队列层次结构和/或重定队列目标的代码(因为你的块可以在任何地方结束)。@Jano你还没有理解我的评论。这与ipmcc的答案有关,所以我回答的是“我想不出有什么理由在您已经在的同一个并发队列上调度_sync”,而不是最初的问题。原因可能是:您肯定希望在该队列上完成任务。你不知道你是否已经开始了。是的,您可以编写代码来检查这一点,但您只是在复制Apple已经编写的代码,因此有一个很好的理由不这样做。@Tommy您需要小心这一点:如果您确实知道要在(Q1)上完成任务的队列是并发的,那么您可以这样做。但如果您不知道当前在哪个队列上执行(Q?),则可能不知道Q1是否并发。如果它是串行的,并且Q1==Q?,那么
向它发送同步将使您死锁。您可能可以使用
dispatch_queue_uu[get | set]_specific
dispatch_get_specific
来解决这个问题,但前提是没有其他人使用该功能来处理您可能遇到的任何问题。@ipmcc我完全同意。而且,为了记录在案,我想到的唯一人为的情况是,其中一个全局队列上的某个东西想要以
调度\u队列\u优先级低的方式调度进一步的工作,但不知道自己的优先级。也许您已经有了一个web服务,它涉及到昂贵的解析和簿记来存储以供重用。解析看起来总是一样的,但您可以将其作为
dispatch\u QUEUE\u PRIORITY\u HIGH
dispatch\u QUEUE\u PRIORITY\u LOW
进行调度,这取决于它是用于现在还是将来的用户界面。你总是以低优先级记账。