How to control and balance the number of threads executed by my application, how to limit their number to avoid blocking applications, because the thread limit is reached?
Here on SO, I saw the following possible answer: "The main parallel queue (dispatch_get_global_queue) controls the number of threads automatically", which I don't like for the following reason:
Consider the following pattern (in my real application there are simpler and more complex examples):
dispatch_queue_t defaultBackgroundQueue() { return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); } dispatch_queue_t databaseQueue() { dispatch_queue_create("Database private queue", 0); } dispatch_async(defaultBackgroundQueue(), ^{ [AFNetworkingAsynchronousRequestWithCompletionHandler:^(data){ dispatch_async(databaseQueue(), ^{ // data is about 100-200 elements to parse for (el in data) { } maybe more AFNetworking requests and/or processing in other queues or dispatch_async(dispatch_get_main_queue(), ^{ // At last! We can do something on UI. }); }); }]; });
This scheme very often leads to a situation when:
- The application is blocked due to the thread limit being reached (something like> 64).
- slower and therefore narrower queues can be overloaded with a large number of pending jobs.
- the second can also cause a cancellation problem - if we have 100 jobs that are already waiting to be completed in a sequential queue, we cannot immediately cancel them.
An obvious and dumb solution would be to replace sensitive dispatch_async methods with dispatch_sync, but this is definitely one that I don't like.
What approach is recommended for such situations?
I hope the answer is smarter than just “Use NSOperationQueue - it can limit the number of concurrent operations” (similar topic: Number of threads with NSOperationQueueDefaultMaxConcurrentOperationCount ).
UPDATE 1: the only decent template: replace all dispatch_async blocks with parallel queues with the launch of these blocks wrapped in NSOperations in parallel queues based on NSOperationQueue with the maximum set of maximum operations (in my case, you can also set the max limit of operations in the NSOperationQueue queue in which AFNetworking performs all its operations).
source share