我需要通过后台线程下载图像,但限制线程数。最大线程数必须为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");
});
答案 0 :(得分:3)
GCD无法限制运行的并发块数量。
这可能会创建一个等待您入队的每个操作的线程。 GCD动态调整它使用的线程数。如果你排队另一个块并且GCD没有更多可用线程,如果它注意到有可用的空闲CPU核心,它将启动另一个线程。由于工作线程在块内部休眠,因此CPU被认为是空闲的。这将导致许多线程占用大量内存 - 每个线程获得512 KB的堆栈。
您最好的选择是使用NSOperationQueue,因为您可以使用maxConcurrentOperationCount属性直接控制并行运行的操作数。这将更容易(编写,测试和调试的代码更少)并且效率更高。