42

我正在编写一个中等复杂的 iOS 程序,它的一些较长的操作(解析、网络连接等)需要多个线程。但是,我对 和 之间的区别感到dispatch_get_global_queue困惑dispatch_queue_create

我应该使用哪一个,你能给我一个简单的解释,说明一般有什么区别吗?谢谢。

4

3 回答 3

71

文档所述,全局队列适用于并发任务(即,您将异步调度各种任务,如果它们同时运行,您将非常高兴)并且如果您不想遇到创建和破坏你自己的队列。

如果您需要一个串行队列(即您需要一次执行一个已调度的块),则创建您自己的队列非常有用。这在许多情况下都很有用,例如当每个任务都依赖于前一个任务或协调与来自多个线程的某些共享资源的交互时。

不太常见,但如果您需要将屏障与并发队列结合使用,您还需要创建自己的队列。在这种情况下,创建一个并发队列(即dispatch_queue_create使用DISPATCH_QUEUE_CONCURRENT选项)并将屏障与该队列一起使用。你永远不应该在全局队列上使用屏障。

我的一般建议是,如果您需要串行队列(或需要使用屏障),请创建一个队列。如果您不这样做,请继续使用全局队列并绕过创建自己的队列的开销。


如果你想要一个并发队列,但又想控制可以同时运行多少个操作,你也可以考虑使用NSOperationQueuewhich has a maxConcurrentOperationCountproperty。这在进行网络操作并且您不希望向服务器提交太多并发请求时很有用。

于 2012-06-11T18:38:28.700 回答
42

刚刚发布了一个不同的答案,但这是我很久以前写的:

将队列概念化的最好方法是首先意识到在非常低的级别上,只有两种类型的队列:串行和并发。

串行队列是一夫一妻制的,但未提交。如果你给每个串行队列分配一堆任务,它会一次运行一个,一次只使用一个线程。未提交的方面是串行队列可能会在任务之间切换到不同的线程。串行队列总是在执行下一个任务之前等待一个任务完成。因此,任务按 FIFO 顺序完成。您可以使用dispatch_queue_create.

队列是一个特殊的串行队列。与其他未提交的串行队列不同,它们与许多线程“约会”,但一次只与一个线程“约会”,主队列与主线程“结婚”,所有任务都在其上执行。主队列上的作业需要在运行循环中表现良好,这样小操作就不会阻塞 UI 和其他重要位。像所有串行队列一样,任务按 FIFO 顺序完成。

如果串行队列是一夫一妻制的,那么并发队列是混杂的。他们会将任务提交到任何可用的线程,甚至根据系统负载创建新线程。他们可以在不同的线程上同时执行多个任务。重要的是提交到全局队列的任务是线程安全的并尽量减少副作用。任务按 FIFO 顺序提交执行,但不保证完成顺序。在撰写本文时,只有三个并发队列,您无法创建它们,您只能使用dispatch_get_global_queue.

编辑:博客文章扩展了这个答案:http ://amattn.com/p/grand_central_dispatch_gcd_summary_syntax_best_practices.html

于 2012-12-16T07:21:05.227 回答
0

一个返回现有的全局队列,另一个创建一个新的。我会考虑使用 NSOperation 和操作队列,而不是使用 GCD。您可以在本指南中找到有关它的更多信息。通常,您希望操作同时执行,您希望创建自己的队列并将操作放入其中。

于 2012-06-11T18:07:21.570 回答