Глобальная параллельная очередь GCD не всегда параллельная (устройство iOS)? - PullRequest
1 голос
/ 23 ноября 2011

На устройстве iOS я недавно обнаружил, что странное поведение.

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);
    }
});

Кодекса2:

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);
    }
});

Код1 и Код2 отличаются только тем, что Код1 спит 1 секунду каждый цикл, а Код2 спит 0,5.

Если вы запустите эти два кода на устройстве iOS с одним ядром, Code1 напечатает @ 1111, а Code2 - нет.

Не знаю, почему глобальная очередь считается параллельной. Она всегда должна выводить число независимо от того, что делают другие блоки. И если это что-то из-за ограничения этого одноядерного устройства, почему sleep (0.5) и sleep (1) будут иметь значение?

Я действительно хочу знать причину этого.

EDIT Я обнаружил, что использование сна (0.5) - моя глупая ошибка. Функция sleep() принимает параметр типа unsigned int. Таким образом, sleep (0.5) равно sleep (0). Но блокирует ли сон (0) всю параллельную очередь?

Ответы [ 2 ]

3 голосов
/ 25 ноября 2011

Причина в том, что ваш второй sleep () по сути является sleep (0), что означает, что вы теперь зацикливаете поток, который вам дал GCD, и это, вероятно, тот же поток, который выполнил бы вложенный dispatch_async() если вы дали ему возможность сделать что-то еще, что делает первый пример.В течение одной секунды GCD видит, что поток заблокирован, и создает новый для обслуживания невыполненных запросов в очереди.Во втором примере вы, по сути, вычислительно лишаете работу в очереди - GCD недостаточно умен, чтобы знать, что поток заблокирован в бесконечном цикле, и вы не даете системе достаточно работы, чтобы оправдать (в глазах GCD)создание другого потока, так что ... вы, по-моему, обнаружили ошибку в нижнем пороге рабочей логики GCD, я думаю.

0 голосов
/ 23 ноября 2011

Только что выписано, 1-й и 2-й фрагменты печатают «1111». Обратите внимание, что вложенность используемого вами dispatch_async не даст никакой прибыли, поскольку вы устанавливаете одинаковые приоритеты (DISPATCH_QUEUE_PRIORITY_DEFAULT) для всех задач "NSLog(@"1111");"

и "

while (1) {
        sleep(0.5);

"

будет добавлено в ту же целевую очередь. В результате я могу предположить, что в первом случае блок с WHILE будет выполняться первым, и поскольку он никогда не завершится, следующая задача в очереди (NSLog (...)) никогда не будет вызвана.

Вы можете попытаться использовать разные приоритеты для очередей (DISPATCH_QUEUE_PRIORITY_LOW и т. Д.).

...