GCD global concurrent queue not always concurrent(iOS device)?

有些话、适合烂在心里 提交于 2019-12-23 03:27:48

问题


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?


回答1:


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.




回答2:


Just checked out, 1st and 2nd snippets print "1111". Note, nesting of dispatch_async you use won't give any profit, because you set the same priorities (DISPATCH_QUEUE_PRIORITY_DEFAULT) all the tasks "NSLog(@"1111");"

and "

while (1) {
        sleep(0.5);

"

will be added to the same target queue. As the result I can assume that in the first case block with WHILE will be executed first, and because it will not finish never, the next task in the queue(NSLog(...)) will be never called.

You can try to use different priorities for the queues (DISPATCH_QUEUE_PRIORITY_LOW f.e.).



来源:https://stackoverflow.com/questions/8239436/gcd-global-concurrent-queue-not-always-concurrentios-device

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!