使用 Grand Central Dispatch (GCD) 创建恰好 N 个线程

Posted

技术标签:

【中文标题】使用 Grand Central Dispatch (GCD) 创建恰好 N 个线程【英文标题】:Creating exactly N threads with Grand Central Dispatch (GCD) 【发布时间】:2013-02-06 11:23:13 【问题描述】:

我知道我可以使用dispatch_asyncdispatch_get_global_queue 异步执行任务。

但是 dispatch_async 创建了多少线程? 我应该怎么做才能用 GCD 准确地执行 N 个(不多也不少)线程,并在它们上执行一些任务?执行任务后,我需要在已发布的线程中添加新任务,可能在前一个任务的编译块中。

或者也许我可以用NSOperationQueue 控制线程数? 我知道它有属性maxConcurrentOperationCount,但它只控制任务的最大限制。那么,如果我设置 maxConcurrentOperationCount = 8 并向NSOperationQueue 添加 12 个操作,我可以确定 NSOperationQueue 创建不少于 8 个线程吗?

非常感谢!

【问题讨论】:

为什么?使用 GCD 的原因是为了避免我们寻找最佳线程数。如果你想要 N 个线程,然后使用 NSThread 自己创建它们 实践中没有理由,只是为了研究。 maxConcurrentOperationCount 只是一个最大值。它可以创造更少。如果您需要精确控制线程数,则必须自己管理它们。 @xlc 这很有用的原因是,如果您的应用程序调度太多操作,您会占用系统,最终阻塞进程中的主队列。我觉得它是 GCD 中一个相当明显的遗漏,以及为什么我现在通常使用操作队列。这种遗漏破坏了 GCD 对大规模并行操作的许多好处。 @Rob 我知道在 osx 中有最大 64 个工作线程的限制,不确定 ios。如果 CPU 没有被充分利用(这就是使用 GCD 的全部意义),GCD 也只会产生新线程。我同意使用 GCD 创建 64 个繁忙的工作线程是可能的,但如果你正确使用它就不太可能发生。 【参考方案1】:

您应该查看NSThread。如果您需要精确控制要运行的线程数,这是您的最佳选择。

【讨论】:

【参考方案2】:

子类NSOperation 用于您想要执行的任务并将它们放入NSOperationQueue。您可以设置队列上的并发操作数。

NSOperationQueue *q = [[NSOperationQueue alloc] init];
q. maxConcurrentOperationCount = N;

【讨论】:

但是属性叫 maxConcurrentOperationCount,我认为它只设置了最大线程数而不是最小线程数,对吗? 没错。但是,如果您将最大值设置为 6 并且肯定只添加 5 个操作,那么最好不要创建最后一个未使用的线程,直到您需要它? @deanWombourne +1 我同意使用NSOperationQueue 是设置最大值(但不是最小值)的好方法。但是您建议您需要子类化NSOperation,但显然这不是必需的(90-95% 的时间,当我使用操作队列时,我只是做addOperationWithBlock 并且根本不创建自己的操作。而当我需要创建操作(例如控制dependencies)时,我经常使用NSOperationBlock 之类的。当然,如果您的应用程序需要,您可以子类化,但通常这是不必要的。【参考方案3】:

队列的概念不同于线程。通过 NSThread 类。由于 NSOperation 使用 GCD,你不能从这里设置线程。您可以合并 NSThread 和 NSOperation 创建和传递不同的线程。 但是你为什么要这样做呢?更多的线程并不意味着更快的速度,通常是相反的,对内存、锁定、并发等有很多关注。 你应该有一个非常具体的原因。

【讨论】:

【参考方案4】:

如果你想在使用 gcd 时控制最大线程数,你可以使用DispatchSemaphore。首先,创建一个具有最大计数的semaphore,然后在任务开始时创建semaphore.wait(),最后在任务结束时创建semaphore.signal()

【讨论】:

以上是关于使用 Grand Central Dispatch (GCD) 创建恰好 N 个线程的主要内容,如果未能解决你的问题,请参考以下文章

暂停和恢复 Grand Central Dispatch 线程

使用 Grand Central Dispatch (GCD) 创建恰好 N 个线程

NSOperation 与 Grand Central Dispatch

核心数据和线程/ Grand Central Dispatch

使用图层和 Grand Central Dispatch 呈现 UIButton 的最快方法?

iOS 中的 JSON 请求 - 使用 Grand Central Dispatch 或 NSURLConnection