Великий Центральный Диспетчер против NSThreads? - PullRequest
29 голосов
/ 11 февраля 2012

Я искал множество источников, но не совсем понял разницу между использованием NSThreads и GCD. Я совершенно новичок в платформе OS X, поэтому, возможно, я неправильно истолковал это.

Из того, что я читаю онлайн, GCD, кажется, делает то же самое, что и основные потоки (POSIX, NSThreads и т. Д.), Добавляя при этом гораздо больше технических терминов ("блоков"). Кажется, что это просто усложняет базовую систему создания потоков (создание потока, функция запуска).

Что такое GCD и почему он будет предпочтительнее традиционного многопоточности? Когда следует использовать традиционные потоки, а не GCD? И, наконец, есть ли причина странного синтаксиса GCD? («блоки» вместо простого вызова функций).

Я нахожусь на Mac OS X 10.6.8 Snow Leopard, и я не программирую для iOS - я программирую для Mac. Я использую Xcode 3.6.8 в Какао, создаю приложение с графическим интерфейсом.

Ответы [ 4 ]

47 голосов
/ 11 февраля 2012

Преимущества отправки

Преимущества отправки в основном описаны здесь:

Миграция от потоков

Идея состоит в том, что вы исключаете работу с вашей стороны, так как парадигма легче вписывается в код MOST.

  • Это уменьшает потери памяти, которые ваше приложение платит за хранение стеков потоков в пространстве памяти приложения.
  • Устраняет код, необходимый для создания и настройки ваших потоков.
  • Устраняет код, необходимый для управления и планирования работы над потоками.
  • Упрощает код, который необходимо написать..

Опытным путем использование блокировки типа GCD вместо @synchronized происходит на 80% быстрее или более, хотя микропроцессоры могут быть обманчивы.Подробнее здесь , хотя я думаю, что совет по асинхронности с записью во многих случаях не применим, и он медленнее (но асинхронный).

Преимущества потоков

Почему вы продолжаете использовать темы?Из того же документа:

Важно помнить, что очереди не являются панацеей для замены потоков.Модель асинхронного программирования, предлагаемая очередями, подходит в ситуациях, когда задержка не является проблемой.Хотя очереди предлагают способы настройки приоритета выполнения задач в очереди, более высокие приоритеты выполнения не гарантируют выполнение задач в определенное время.Поэтому потоки все еще являются более подходящим выбором в тех случаях, когда вам нужна минимальная задержка, например, при воспроизведении аудио и видео.

Еще одним местом, где я лично не нашел идеального решения с использованием очередей, является демонпроцессы, которые должны быть постоянно перенесены.Не то, чтобы вы не могли перенести их, но цикл внутри метода NSThread проще (я думаю). Редактировать: Теперь я убежден, что даже в этом контексте блокировка в стиле GCD будет быстрее, и вы также можете сделать цикл внутри операции, отправляемой GCD.

Блоки в Objective-C?

В Objective-C блоки действительно ужасны из-за ужасного синтаксиса (хотя Xcode иногда может помочь с автозаполнением, по крайней мере).Если вы посмотрите на блоки в Ruby (или на любом другом языке), то увидите, насколько они просты и изящны для диспетчерских операций.Я бы сказал, что вы привыкнете к синтаксису Objective-C, но я действительно думаю, что вы привыкнете много копировать из своих примеров:)

Вы можете найти моих примеровотсюда чтобы быть полезным или просто отвлекающим.Не уверен.

11 голосов
/ 11 февраля 2012

Хотя ответы до сих пор касаются контекста потоков против GCD внутри домена одного приложения и его различий в программировании, причина, по которой вы всегда должны отдавать предпочтение GCD, связана с многозадачной средой (поскольку вы работаете в MacOSX и не iOS). Потоки в порядке, если ваше приложение работает в одиночку на вашем компьютере. Скажем, у вас есть программа для редактирования видео, и вы хотите применить к видео какой-то эффект. Рендеринг займет 10 минут на машине с восемью ядрами. Хорошо.

Теперь, пока видео приложение работает в фоновом режиме, вы открываете программу для редактирования изображений и играете с каким-то изображением высокого разрешения, решаете применить специальный фильтр изображений, и ваше приложение для обработки изображений обнаруживает, что у вас восемь ядер и запускается восемь потоки для обработки изображения. Хорошо, не правда ли? За исключением того, что это ужасно для производительности. Приложение для редактирования изображений ничего не знает о приложении для видео (и наоборот), и поэтому оба будут запрашивать, соответственно, оптимальное количество потоков. И будет боль и кровь, пока ядра будут пытаться переключаться с одного потока на другой, потому что во избежание голодания ЦП в конечном итоге позволит запустить все потоки, хотя в этой ситуации было бы более оптимальным запускать только 4 потока для видео app и 4 темы для приложения image.

Для более подробного ознакомления взгляните на http://deusty.blogspot.com/2010/11/introducing-gcd-based-cocoahttpserver.html, где вы можете увидеть эталонный тест HTTP-сервера, использующего GCD по сравнению с потоком, и посмотреть, как он масштабируется. После того, как вы поймете, с какими потоками связаны многоядерные машины в многозадачных средах, вы всегда захотите использовать GCD просто потому, что потоки не всегда оптимальны, в то время как GCD потенциально может быть таковой, поскольку ОС может масштабировать использование потоков для каждого приложения в зависимости от нагрузки.

Пожалуйста, помните, что в ближайшее время на наших машинах не будет больше ГГц. Отныне у нас будет только больше ядер, поэтому вы должны использовать лучший инструмент для этой среды, а именно GCD.

9 голосов
/ 11 февраля 2012

Блоки позволяют передавать блок кода для выполнения.Как только вы преодолеете «странный синтаксис», они станут достаточно мощными.

GCD также использует очереди, которые при правильном использовании могут помочь с параллельным доступом без блокировки, если код, выполняемый в отдельных очередях, изолирован.Это более простой способ предложить фон и параллелизм при минимальной вероятности возникновения взаимоблокировок (если используется правильно).

«Странный синтаксис» заключается в том, что они выбрали каретку (^), потому что это был один из немногих символов, которыене был перегружен как оператор в C ++

См .: https://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

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

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

...

Хотя было бы правильным указать, что две задачи, выполняющиеся в последовательной очереди, не выполняются одновременно, выНеобходимо помнить, что если два потока принимают блокировку одновременно, любой параллелизм, предлагаемый потоками, теряется или значительно уменьшается.Что еще более важно, многопоточная модель требует создания двух потоков, которые занимают как ядро, так и пользовательскую память.Очереди отправки не платят одинаковое штраф за память для своих потоков, и потоки, которые они используют, остаются занятыми и не блокируются.

2 голосов
/ 02 мая 2017

GCD (Grand Central Dispatch): GCD предоставляет и управляет очередями FIFO, в которые ваше приложение может отправлять задачи в виде блочных объектов.Работа, отправляемая в очереди отправки, выполняется в пуле потоков, полностью управляемых системой.Не дается никаких гарантий относительно потока, в котором выполняется задача.Почему GCD поверх потоков:

Сколько работы делают ваши ядра CPU Сколько у вас ядер CPU.Сколько потоков должно быть создано.Если GCD нужен, он может войти в ядро ​​и обмениваться информацией о ресурсах, таким образом, улучшая планирование.Меньшая нагрузка на ядро ​​и лучшая синхронизация с ОС GCD использует существующие потоки из пула потоков вместо создания, а затем уничтожения.Наилучшее использование аппаратных ресурсов системы, позволяя операционной системе сбалансировать нагрузку всех программ, запущенных в настоящее время, с учетом таких факторов, как нагрев и срок службы батареи.

Я поделился своим опытом с потоками, операционной системой и GCDAT http://iosdose.com

...