On iOS device, I recently found that a strange behavior.
Code1:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"1111");
});
while (1) {
sleep(1);
}
});
Code2:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"1111");
});
while (1) {
sleep(0.5);
}
});
Code1 and Code2’s only difference is that Code1 sleep 1second every loop and Code2 sleep 0.5.
If you run these two code on iOS device with single core, Code1 will print out the @”1111″, but Code2 won’t.
I don’t why, the global queue is assumed to be concurrent.It should always print out the number no matter what other blocks are doing. And if it is something due to that single core device’s limit, why sleep(0.5) and sleep(1) would make the difference?
I really want to know the reason for this.
EDIT
I found use sleep(0.5) is my stupid mistake. sleep() function take an unsigned int parameter.So sleep(0.5) is equal to sleep(0). But do sleep(0) will block the whole concurrent queue?
The reason is that your second sleep() is essentially a sleep(0) which means that you’re now buzz-looping the thread that GCD gave to you, and that’s probably the same thread that would have executed the nested dispatch_async() if you had given it a chance to do anything else, which the first example does. During the one second sleep, GCD sees that the thread is blocked and creates a new one to service the outstanding queued request(s). In the second example, you’re essentially computationally starving the enqueued work – GCD is not smart enough to know that a thread has been locked into an infinite loop, and you’re not giving the system enough work to justify (in GCD’s eyes) the creation of another thread, so… You’ve essentially discovered a bug in GCD’s low-threshold of work logic, I think.