限制线程数

时间:2015-06-14 11:50:28

标签: objective-c multithreading grand-central-dispatch

我需要通过后台线程下载图像,但限制线程数。最大线程数必须为5,并且每个线程必须只是一个串行队列。对于使用套接字火箭库的客户端服务器。主要的麻烦是我不需要取消操作等NSOperation。寻找一个简单的决定,但可以找到这样的东西:

self.limitingSema = dispatch_semaphore_create(kOperationLimit);
    dispatch_queue_t concurentQueue = dispatch_queue_create("limiting queue", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(concurentQueue, ^{
        dispatch_semaphore_wait(self.limitingSema, DISPATCH_TIME_FOREVER);

        /* upload image here */

        dispatch_semaphore_signal(self.limitingSema);
    });

但接下来如何限制线程数并等待新操作开始,直到它们没有在队列中准备好?

控制队列数是否合适?

NSArray *queues = @[dispatch_queue_create("com.YOU.binaryQueue_1", DISPATCH_QUEUE_SERIAL),
                    dispatch_queue_create("com.YOU.binaryQueue_2", DISPATCH_QUEUE_SERIAL),
                    dispatch_queue_create("com.YOU.binaryQueue_3", DISPATCH_QUEUE_SERIAL)
                    ];

NSUInteger randQueue = arc4random() % [queues count];
dispatch_async([queues objectAtIndex:randQueue], ^{
    NSLog(@"Do something");
});
randQueue = arc4random() % [queues count];
dispatch_async([queues objectAtIndex:randQueue], ^{
    NSLog(@"Do something else");
});

1 个答案:

答案 0 :(得分:3)

GCD无法限制运行的并发块数量。

这可能会创建一个等待您入队的每个操作的线程。 GCD动态调整它使用的线程数。如果你排队另一个块并且GCD没有更多可用线程,如果它注意到有可用的空闲CPU核心,它将启动另一个线程。由于工作线程在块内部休眠,因此CPU被认为是空闲的。这将导致许多线程占用大量内存 - 每个线程获得512 KB的堆栈。

您最好的选择是使用NSOperationQueue,因为您可以使用maxConcurrentOperationCount属性直接控制并行运行的操作数。这将更容易(编写,测试和调试的代码更少)并且效率更高。