GCD问题和线程太多 [英] Issue with GCD and too many threads

查看:104
本文介绍了GCD问题和线程太多的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个图像加载器类,它提供了来自Web的NSURL加载和图像,并执行完成块。代码实际上非常简单

I have an image loader class which provided with NSURL loads and image from the web and executes completion block. Code is actually quite simple

- (void)downloadImageWithURL:(NSString *)URLString completion:(BELoadImageCompletionBlock)completion
{
    dispatch_async(_queue, ^{
//    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        UIImage *image = nil;
        NSURL *URL = [NSURL URLWithString:URLString];
        if (URL) {
            image = [UIImage imageWithData:[NSData dataWithContentsOfURL:URL]];
        }  
        dispatch_async(dispatch_get_main_queue(), ^{
            completion(image, URLString);
        });
    });

}

当我替换

dispatch_async(_queue, ^{

已注释掉

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{

图片正在加载很多更快,是的非常符合逻辑(在此之前,一次只能加载一个图像,现在它们中的一堆图像同时加载)。我的问题是我可能有50张图片,我为所有这些调用了downloadImageWithURL:completion:方法,当我使用全局队列而不是_queue时,我的应用程序最终崩溃,我看到有85个以上的线程。可能问题是我连续50次调用dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0)会让GCD创建太多线程吗?我认为gcd处理所有的treading并确保线程的数量不是很大,但是如果不是这样的话,我有什么方法可以影响线程的数量?

Images are loading much faster, wich is quite logical (before that images would be loaded one at a time, now a bunch of them are loading simultaneously). My issue is that I have perhaps 50 images and I call downloadImageWithURL:completion: method for all of them and when I use global queue instead of _queue my app eventually crashes and I see there are 85+ threads. Can the problem be that my calling dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0) 50 times in a row makes GCD create too many threads? I thought that gcd handles all the treading and makes sure the number of threads is not huge, but if it's not the case is there any way I can influence number of threads?

推荐答案

http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html


并发队列(也称为一种全局调度队列)同时执行一个或多个任务,但任务仍以
的顺序从它们添加到队列的顺序开始。当前
执行任务在由
调度队列管理的不同线程上运行。在任何给定点执行的任务的确切数量
是可变的,取决于系统条件。

Concurrent queues (also known as a type of global dispatch queue) execute one or more tasks concurrently, but tasks are still started in the order in which they were added to the queue. The currently executing tasks run on distinct threads that are managed by the dispatch queue. The exact number of tasks executing at any given point is variable and depends on system conditions.


串行队列(也称为私有调度队列)按照它们添加到队列的顺序一次执行一个任务

当前正在执行的任务在由调度队列管理的不同线程(可以在任务之间改变
)上运行。

Serial queues (also known as private dispatch queues) execute one task at a time in the order in which they are added to the queue. The currently executing task runs on a distinct thread (which can vary from task to task) that is managed by the dispatch queue.

通过

[NSData dataWithContentsOfURL:URL]

这是一个同步阻塞网络操作,看起来默认的GCD行为是产生一个负载线程尽快执行你的块。

which is a synchronous blocking network operation, it looks like the default GCD behaviour will be to spawn a load of threads to execute your blocks ASAP.

你应该派遣到 DISPATCH_QUEUE_PRIORITY_BACKGROUND 。这些任务绝不是高优先级。任何图像处理应该在有空闲时间时完成,并且主线程上没有任何事情发生。

You should be dispatching to DISPATCH_QUEUE_PRIORITY_BACKGROUND. These tasks are in no way "High Priority". Any image processing should be done when there is spare time and nothing is happening on the main thread.

如果你想要更多地控制这些事情中有多少一次发生我建议您考虑使用 NSOperation 。您可以使用 NSBlockOperation 来获取块并将其嵌入到操作中,然后您可以将这些操作提交到您自己的 NSOperationQueue NSOperationQueue 具有 - (NSInteger)maxConcurrentOperationCount ,并且如果需要,还可以在计划后取消添加的权益操作。

If you want more control over how many of these things are happening at once i reccommend that you look into using NSOperation. You can take your blocks and embed them in an operation using NSBlockOperation and then you can submit these operations to your own NSOperationQueue. An NSOperationQueue has a - (NSInteger)maxConcurrentOperationCount and as an added benefit operations can also be cancelled after scheduling if needed.

这篇关于GCD问题和线程太多的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆