iOS上的GCD可以处理数百个调度块吗?

时间:2013-11-10 04:08:17

标签: multithreading performance asynchronous grand-central-dispatch

我想将GCD用于一百个对象,这些对象都需要从服务器下载一些数据。如果我要遍历这些对象,并调用类似的东西:

dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_async(q, ^{
    // Download data;
});

这些块会智能地排队并有效执行,还是会遇到内存问题,性能问题甚至竞争条件?

我的两分钱是这些块将按照名称建议排队,并且下载将一次启动一个,只要我正在清理,如果应用程序在所有下载完成之前终止,则不应该是问题。

然而,另一个红利问题是:

如果我通过在队列之间分配下载来创建3-5个队列并一次下载多个文件,我会受益吗?


实现此功能后,似乎接受的答案未完成,或者我错过了重点。在全局队列上调度块(这是一个并发队列)可能会导致问题,因为GCD可以调度最大数量的线程(~64)。这仅适用于并发队列,因为它们需要为每个操作生成一个线程。但是,如果您创建自己的队列,那么该队列将是一个一个接一个地执行块的顺序队列,即使调用dispatch_async也是如此。这样,您可以确定您的队列只会生成1个线程,并对您的操作进行排队,并且永远不会遇到线程限制问题。

2 个答案:

答案 0 :(得分:4)

解决你的第一堆问题,即“这些块是否会智能地排队并有效执行,或者我会遇到内存问题,性能问题甚至竞争条件”。

我的回答:

  1. 这些街区是否会智能地排队并有效执行:是的,他们毫无疑问。

  2. 我是否会遇到内存问题,性能问题:这取决于情况。由于您正在调用异步方法,因此它不会保证第一个下载操作将在第一个完成后启动。如果您正在使图像或视频发生故障,则由于CFDATA或CFDATA(存储)问题(可以处理)可能会出现内存不足问题。

  3. 甚至是竞争条件:如果您知道如何以及何时切换线程,您将永远不会陷入竞争状态。例如:如果下载类需要在主线程上调用委托,则需要在主线程上启动连接,如NSURLConnection。如果你在donwload之后处理UI元素,你仍然需要切换你的线程。其他方面没有竞争条件或死锁。

  4. 解决你的第二个问题“如果我通过在队列中分配下载来创建3-5个队列并一次下载多个文件,我会受益更多吗?”

    如果我会在你的位置,我会用单个队列去掉数百个对象。我一直在这种情况下,在我的情况下,我必须下载数千个文件。我会一次去单个文件下载并清理然后继续前进。好像你有数百个要下载的文件,即使0.1 MB的额外分配也会导致性能问题。

答案 1 :(得分:0)

来自MacOS X和iOS的并发编程(O'Reilly):

enter image description here