Количество потоков, созданных GCD? - PullRequest
25 голосов
/ 27 августа 2011

Есть ли какая-нибудь хорошая документация по , сколько потоков создано GCD? На WWDC нам сказали, что это моделируется ядрами процессора. Однако, если я назову этот пример:

for (int i=1; i<30000; i++) {
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        [NSThread sleepForTimeInterval:100000];
    });
}

открывает 66 потоков даже на iPad1. (Он также открывает 66 потоков при непосредственном вызове Lion). Почему 66?

Ответы [ 3 ]

29 голосов
/ 02 сентября 2011

Во-первых, 66 == 64 (максимальный размер пула потоков GCD) + основной поток + некоторый другой случайный поток не-GCD.

Во-вторых, GCD не волшебство.Он оптимизирован для загрузки ЦП кодом, который в основном связан с ЦП.«Магия» GCD заключается в том, что он динамически создает больше потоков, чем процессоров, когда рабочие элементы непреднамеренно и ненадолго ждут завершения операций.

Сказав это, код может сбить с толку планировщик GCD, умышленно спя или ожидая событийвместо использования источников отправки для ожидания событий.В этих сценариях блок работ эффективно реализует свой собственный планировщик, и поэтому GCD должен предполагать, что поток был выбран из пула потоков.

Короче говоря, пул потоков будет работать оптимально, если ваш кодпредпочитает dispatch_after () над API-интерфейсами типа sleep (), а источники рассылки - над циклами событий, созданными вручную (Unix select () / poll (), циклы запуска Какао или условные переменные POSIX).

2 голосов
/ 27 августа 2011

В документации не упоминается количество созданных потоков. Главным образом потому, что оптимальное количество потоков сильно зависит от контекста.

Одна проблема с Grand Cendral Dispatch заключается в том, что он создаст новый поток, если запущенное задание блокируется. То есть вы должны избегать блокировок при использовании GCD, поскольку наличие большего количества потоков, чем ядер, является неоптимальным.

В вашем случае GCD обнаруживает, что задача неактивна, и создает новый поток для следующей задачи.

Почему 66 - предел выше меня.

0 голосов
/ 01 июня 2019

Количество занятых потоков равно ядрам процессора.Заблокированные потоки (вы блокируете их с помощью sleepForTimeInterval) не учитываются.

Если вы измените свой код на (Swift):

for _ in 1..<30000 {
    DispatchQueue.global().async {
        while true {}
     }
}

, вы увидите, что их всего 2созданные потоки (на iPhone SE):

enter image description here

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

Никогда не блокируйте потоки, и вы получите их столько же, сколько ваши ядра.

...