3

Typically NSOperationQueue guarantees thats that tasks with low priorities will not be executed until tasks with high priorities are done executing. However, when a large number of operations are added quickly to the queue, sometimes the operation queue can overload, as shown below

enter image description here

This graph tracks the history of 1000 operations. The red line shows the number of tasks with NSOperationQueueVeryLowPriority priority that are currently executing, the green line shows the number of tasks with NSOperationQueueNormalPriority that are idle in the queue and NOT executing, and finally the blue line shows the total number of operations in the queue.

Now, the default max concurrency of the NSOperationQueue in this case seems to be 64. When all of those 64 slots get filled up, even if tasks with higher priorities exists, they don't get executed and have to wait. My question is, is there some way to tweak the NSOperationQueue so that even when under load, it reserves some of the capacity for higher priority operations?

Tony
  • 36,591
  • 10
  • 48
  • 83
  • I'm having a related issue where my high priority operations are executing after normal priority operations. Can't wait to get some answers on this thread! – raidfive Jan 27 '12 at 23:44
  • I was thinking of implement my own subclass to take care of the reserved capacity etc. However, it turns out that for my situation all I needed was a smaller maxConcurrentOperationCount. This allows tasks to complete fast enough (as oppose to 64 task each executing somewhat slowly) that the delay was negligible in the end. – Tony Jan 28 '12 at 21:16
  • Yes, I noticed this earlier today. I have no idea why the system would decide to run 64 concurrent tasks...I figured it would throttle that down and give priority to others. – raidfive Jan 29 '12 at 11:07
  • Yea, those operations with background priority was making my system spin like crazy with this 64 concurrent tasks. (I guess that's the whole point of letting system manage the max concurrent count - to maximize system resource...) But throttling it down to 16 or even 8 improves substantially the time takes for each task (I only have 2 cores, not 64 ...) – Tony Jan 29 '12 at 16:54

1 Answers1

1

I have a similar problem with NSOperation & NSOperationQueue.

I have a class (with NSURLConnection) that inherits from NSOperation. I have the NSOperationQueue setup. I am adding approx 5000-6000 operations to that queue. The problem here is that not all the operations get executed. It stops exactly at 64. Found that the default max-thread-count during concurrent operations seem to be 64 for intel-i5 processor.

Solution is using NSRunLoop: Declared a NSRunLoop that gets the currentLoop. And running the loop for a few seconds. Doing this will exit the currentLoop every few seconds. This way, at any point in time, the max-thread-count is way less than 64. My app just works. :)

biegleux
  • 13,179
  • 11
  • 45
  • 52