2011-08-27 30 views
23

有没有什么好的文档GCD创建了多少个线程? 在WWDC,他们告诉我们它是围绕CPU核心建模的。但是,如果我称这个示例为:GCD创建的线程数量?

for (int i=1; i<30000; i++) { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
     [NSThread sleepForTimeInterval:100000]; 
    }); 
} 

它打开66个线程,即使在iPad1上也是如此。 (它在本地调用Lion时也会打开66个线程)。为什么66?

回答

24

首先,66 == 64(最大GCD线程池大小)+主线程+一些其他随机非GCD线程。

二,GCD不是魔术。它经过优化,可以使CPU忙于大多数CPU绑定的代码。 GCD的“魔力”在于,当工作项目无意中暂时等待操作完成时,它会动态创建比CPU更多的线程。尽管如此,代码可能通过故意睡眠或等待事件而不是使用调度源等待事件来混淆GCD调度器。在这些情况下,工作块有效地实现了自己的调度程序,因此GCD必须假定该线程已从线程池中选择。简单来说,如果你的代码比API更像“sleep()”,并且通过手工事件循环(Unix select()/ poll(),Cocoa runloops或POSIX条件变量)。

+1

“已从线程池中选择”您选择的是什么意思?你的意思是睡觉或其他的挂断将被解释为100%活动,因此该线程将不能用于额外的调度? –

+1

如果你可以在线程池大小上提供这个声明的参考,那么当然会很好 - 我无法在任何地方找到它。 –

1

该文档避免提及创建的线程数。主要是因为线程的最佳数量在很大程度上取决于上下文。

Grand Cendral Dispatch的一个问题是,如果正在运行的任务阻塞,它将产生一个新的线程。也就是说,当使用GCD的线程多于核心不理想时,应避免阻塞。

就你而言,GCD检测到任务处于非活动状态,并为下一个任务产生一个新线程。

为什么66是超越我的限制。

+0

我几乎不能相信66是一个最佳数字,如果文档告诉我,每个线程吃大约半兆RAM。 (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/CreatingThreads/CreatingThreads.html)因此,在66个线程中,我们有大约30兆的开销,这是iOS 64MB限制的一半总。 – steipete

+0

@steipete线程还会消耗上下文切换。所以记忆不应该是决定极限的唯一因素。 – Eonil

+1

@steipete来自同一文档“,但与该内存相关联的实际页面只有在需要时才会创建。”所以,只有在使用时才会声明半个堆栈空间(逐页;即如果你的线程只需要2页堆栈,它只会浪费太多)。此外,Eonil,我们现在有多核CPU,其中上下文切换的成本不太成问题(因为你'只'运行线程的数量等于或少于核心的数量) – tofi9