Получение единого основного потока в программе с использованием GCD
Используя это в качестве системы отсчета, есть ли какая-то причина, по которой следующий пример {не может} / {не приведет} к тому, что пул потоков GCD будет работать исключительно в основном потоке?
int main()
{
dispatch_queue_t myQueue = dispatch_queue_create("myQ",NULL); // create serial queue
//
dispatch_sync(myQueue, ^{/*some simple block*/});
....
dispatch_sync(myQueue, ^{/*some simple block*/});
}
Насколько я понимаю, GCD будет пытаться оптимизировать производительность там, где это возможно, передавая блоки (когда это выгодно) любому доступному потоку. Однако мониторинг этого в xcode показывает, что это может выполняться исключительно в основном потоке. Это не, пока диспетчерские звонки не станут async
что второй поток используется.
Я просто хотел бы понять, когда / почему второй поток может или не может быть вызван. До этого я предполагал, что всегда будет вызываться второй поток.
1 ответ
Вы отправляете блоки, используя dispatch_sync. dispatch_sync ожидает окончания выполнения блока. Поэтому то, что вы делаете, совершенно бессмысленно, если только вы не используете эту последовательную очередь для синхронизации. Там не может быть никакого параллелизма. Напротив, если в последовательной очереди уже выполнялся код и, возможно, блоки, уже отправленные в него, вашему основному потоку пришлось бы ждать, пока завершится работающий блок и все последующие отправленные блоки, а затем дождаться завершения ваших блоков.,
Если бы вы вызвали dispatch_async, то эти два блока были бы отправлены в последовательную очередь, будут выполняться один за другим (используя один процессор), в то время как ваш основной поток продолжал бы делать другие вещи, используя другой процессор.
Если вы вызвали dispatch_async в параллельную очередь, тогда два блока будут выполняться параллельно, в то время как ваш основной поток может выполнять другие операции, используя до трех процессоров.
Теперь ваш код будет "официально" запускать ваши блоки в другом потоке, в то время как основной поток заблокирован. Поскольку потоковые переключатели дороги, по возможности их избегают. Поэтому dispatch_sync для последовательной очереди проверит, является ли очередь пустой, и если она пуста, она заблокирует очередь от отправки, выполнит блок в вызывающем потоке, а затем разблокирует очередь. Поведение точно такое же, как если бы блок был отправлен, но оно выполняется быстрее.