GCD全局并发队列不总是并发(iOS设备)吗? [英] GCD global concurrent queue not always concurrent(iOS device)?

查看:136
本文介绍了GCD全局并发队列不总是并发(iOS设备)吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近在iOS设备上发现了一种奇怪的行为.

On iOS device, I recently found that a strange behavior.

代码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.

Code1 and Code2's only difference is that Code1 sleep 1second every loop and Code2 sleep 0.5.

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

If you run these two code on iOS device with single core, Code1 will print out the @"1111", but Code2 won't.

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

I don't why, the global queue is assumed to be concurrent.It should always print out the number no matter what other blocks are doing. And if it is something due to that single core device's limit, why sleep(0.5) and sleep(1) would make the difference?

我真的很想知道原因.

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

EDIT I found use sleep(0.5) is my stupid mistake. sleep() function take an unsigned int parameter.So sleep(0.5) is equal to sleep(0). But do sleep(0) will block the whole concurrent queue?

推荐答案

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

The reason is that your second sleep() is essentially a sleep(0) which means that you're now buzz-looping the thread that GCD gave to you, and that's probably the same thread that would have executed the nested dispatch_async() if you had given it a chance to do anything else, which the first example does. During the one second sleep, GCD sees that the thread is blocked and creates a new one to service the outstanding queued request(s). In the second example, you're essentially computationally starving the enqueued work - GCD is not smart enough to know that a thread has been locked into an infinite loop, and you're not giving the system enough work to justify (in GCD's eyes) the creation of another thread, so... You've essentially discovered a bug in GCD's low-threshold of work logic, I think.

这篇关于GCD全局并发队列不总是并发(iOS设备)吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆