GCD global concurrent queue not always concurrent(iOS device)?
在 iOS 设备上,我最近发现了一个奇怪的行为。
代码1:
1 2 3 4 5 6 7 8 | 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:
1 2 3 4 5 6 7 8 | 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() 本质上是一个 sleep(0),这意味着你现在正在循环 GCD 给你的线程,这可能是同一个线程如果您给了它一个机会做任何其他事情,则执行嵌套的 dispatch_async(),这是第一个示例所做的。在一秒钟的睡眠期间,GCD 看到线程被阻塞并创建一个新线程来服务未完成的排队请求。在第二个示例中,您实际上是在计算上使排队的工作饿死 - GCD 不够聪明,无法知道线程已被锁定在无限循环中,并且您没有给系统足够的工作来证明(在 GCD \\ 的眼睛)创建另一个线程,所以......我认为你基本上发现了 GCD 的低阈值工作逻辑中的一个错误。
刚刚签出,第 1 和第 2 个片段打印"1111"。
请注意,您使用的 dispatch_async 嵌套不会带来任何好处,因为您为所有任务 "
设置了相同的优先级 (DISPATCH_QUEUE_PRIORITY_DEFAULT)
和"
1 2 | while (1) { sleep(0.5); |
"
将被添加到同一个目标队列中。结果,我可以假设在第一种情况下,带有 WHILE 的块将首先执行,并且因为它永远不会完成,所以队列中的下一个任务(NSLog(...))将永远不会被调用。
您可以尝试为队列使用不同的优先级 (DISPATCH_QUEUE_PRIORITY_LOW f.e.)。