我正在编写一个中等复杂的iOS程序,需要为其一些较长的操作(解析,连接到网络等)提供多个线程。但是,我对dispatch_get_global_queue
和dispatch_queue_create
之间的区别感到困惑。
我应该使用哪一个,你能不能给我一个简单的解释,一般来说有什么区别?感谢。
答案 0 :(得分:70)
正如documentation所描述的那样,全局队列适用于并发任务(即,您将异步调度各种任务,如果它们同时运行,您会非常高兴)并且如果您不想遇到创建和销毁自己队列的理论开销。
如果您需要一个串行队列(即您需要一次执行一个调度块),那么创建自己的队列非常有用。这在许多场景中都很有用,例如当每个任务依赖于前一个任务时,或者协调与来自多个线程的某些共享资源的交互时。
不太常见,但如果需要将barriers与并发队列结合使用,则还需要创建自己的队列。在该场景中,创建并发队列(即dispatch_queue_create
选项DISPATCH_QUEUE_CONCURRENT
)并将障碍与该队列结合使用。你永远不应该在全局队列上使用障碍。
我的总顾问是,如果您需要一个串行队列(或需要使用障碍),那么创建一个队列。如果不这样做,请继续使用全局队列并绕过创建自己的队列的开销。
如果您想要并发队列,但想要控制可以并发运行的操作数,则还可以考虑使用具有maxConcurrentOperationCount
属性的NSOperationQueue
。这在执行网络操作时很有用,并且您不希望将太多并发请求提交到您的服务器。
答案 1 :(得分:40)
刚刚发布了一个不同的答案,但这是我写了很长一段时间的内容:
概念化队列的最佳方法是首先要意识到,在非常低级别,只有两种类型的队列:串行和并发。
串行队列是一夫一妻制,但未提交。如果为每个串行队列分配一堆任务,它将一次运行一个任务,一次只使用一个线程。未提交的方面是串行队列可能会切换到任务之间的不同线程。串行队列始终等待任务完成,然后再转到下一个任务。因此,任务以FIFO顺序完成。您可以使用dispatch_queue_create
生成所需数量的串行队列。
主队列是一个特殊的串行队列。与其他未提交的串行队列不同,因为它们“约会”许多线程但只有一个线程,主队列与主线程“结合”并且所有任务都在其上执行。主队列上的作业需要与runloop良好地运行,以便小操作不会阻止UI和其他重要位。与所有串行队列一样,任务按FIFO顺序完成。
如果串行队列是一夫一妻制,则并发队列是混杂的。他们会将任务提交给任何可用的线程,甚至根据系统负载创建新的线程。他们可以在不同的线程上同时执行多个任务。提交到全局队列的任务是线程安全的并且最小化副作用是很重要的。任务以FIFO顺序提交执行,但不保证完成顺序。在撰写本文时,只有三个并发队列,您无法创建它们,您只能使用dispatch_get_global_queue
获取它们。
编辑:博客文章扩展此答案:http://amattn.com/p/grand_central_dispatch_gcd_summary_syntax_best_practices.html
答案 2 :(得分:0)
一个返回现有的全局队列,另一个创建一个新队列。我会考虑使用NSOperation和操作队列,而不是使用GCD。您可以找到有关它的更多信息in this guide.通常,您希望操作同时执行,您希望创建自己的队列并将操作放入其中。