在iOS设备上,我最近发现了一个奇怪的行为。

代码1:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"1111");
    });
    while (1) {
        sleep(1);
    }
});

代码2:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"1111");
    });
    while (1) {
        sleep(0.5);
    }
});

Code1和Code2的唯一区别是Code1每个循环睡眠1秒,Code2睡眠0.5。

如果您在具有单核的iOS设备上运行这两个代码,则Code1将打印出@“1111”,而Code2则不会。

我不明白为什么全局队列被认为是并发的,无论其他模块在做什么,它都应该总是打印出这个数字。而且,如果这是由于单个核心设备的限制所致,那么为什么sleep(0.5)和sleep(1)会有所作为?

我真的很想知道原因。

编辑
我发现使用sleep(0.5)是我的愚蠢错误。 sleep()函数采用无符号的int参数,因此sleep(0.5)等于sleep(0)。但是sleep(0)是否会阻塞整个并发队列?

最佳答案

原因是您的第二个sleep()本质上是一个sleep(0),这意味着您正在嗡嗡地循环GCD给您的线程,并且如果执行了嵌套的dispatch_async(),则该线程可能是同一线程您已经给了它做其他任何事情的机会,第一个例子做了。在一秒钟的睡眠期间,GCD看到线程被阻塞,并创建了一个新线程来处理未完成的排队请求。在第二个示例中,您实质上是在计算上使排队的工作饿死-GCD不够聪明,无法知道线程已被锁定为无限循环,并且您没有给系统足够的工作以证明(在GCD的眼中)我想,您实质上已经发现GCD的低工作逻辑阈值中的一个错误。

关于ios - GCD全局并发队列不总是并发(iOS设备)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8239436/

10-10 20:48
查看更多