Подтвердить что ты не робот

Поведение dispatch_get_global_queue

Следующий код:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    for (int i=0; i<100000; i++) {
        NSLog(@"HIGH 1 %d", i);
    }
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
    for (int i=0; i<100000; i++) {
        NSLog(@"LOW %d", i);
    }
});
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
    for (int i=0; i<100000; i++) {
        NSLog(@"HIGH 2 %d", i);
    }
});

приводит к смеси с высокими 1, высокими 2 и низкими логами.

Как это сделать, что он печатает журналы с высоким и высоким уровнем одновременно. не являются как high1, так и high2 блогами в одной очереди? Так что не должно быть high1 block finish, прежде чем запускать блок high2?

4b9b3361

Ответ 1

Это зависит от машины, на которой вы работаете. Я подозреваю, что вы используете это на своем Mac, потому что GCD автоматически создаст достаточно потоков для конкретной системы для заданий в глобальных очередях. Итак, у вас, вероятно, есть более одного ядра, поэтому GCD запускает ваши задания на обоих ядрах.

Если вы создаете свою очередь с помощью dispatch_queue_create, вы получаете очередную очередь, и тогда вам гарантируется поведение FIFO.

FWIW (хотя вы не должны полагаться на это поведение), если вы запустите это на iPhone, я подозреваю, что вы увидите поведение последовательной очереди, потому что ваш iPhone одноядерный. Не полагайтесь на это, хотя iPad 2 является многоядерным, я думаю!

ИЗМЕНИТЬ:

Документация для dispatch_get_global_queue:  Возвращает известную глобальную параллельную очередь заданного уровня приоритета.

Ответ 2

Вы только что проиллюстрировали, почему вы не должны вызывать методы, которые не являются потокобезопасными внутри dispatch_async. Если для выполнения дополнительных заданий достаточно процессорных ядер, GCD продолжит работу и будет работать над ними, независимо от того, вернулись ли предыдущие задания в заданной очереди. Такое же поведение может быть достигнуто в OS X 10.7 путем создания собственных очередей с помощью:

dispatch_queue_create(NULL, DISPATCH_QUEUE_CONCURRENT);

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

Ответ 3

dispatch_get_global_queue является видом очереди concurrency. Если вы укажете тот же приоритет для high1 и high2, результатом будет сочетание high1 и high2. После этого это будет низкий результат, поскольку он имеет более низкий приоритет.