2013-09-04 1 views
1

В объективе-c есть (по крайней мере) два подхода к синхронизации одновременных доступов к общему ресурсу. Более старый подход, основанный на блокировке, и новый подход с Grand Central Dispatch (GCD), для последнего с помощью dispatch_sync для отправки всех обращений в общую очередь.Имеет ли диспетчер_sync концептуальное преимущество перед блокировкой?

В заявке Concurrency Programming Guide, section Eliminating Lock-Based Code указано, что «использование замков происходит за счет стоимости. Даже в непротивостоящем случае всегда существует штраф за исполнение, связанный с блокировкой».

Является ли это аргументом в пользу подхода GCD?

Я думаю, что это не по следующей причине:

Очередь должна иметь список задач, поставленных в очередь, чтобы сделать. Один или несколько потоков могут добавлять задачи в этот список через dispatch_sync, и один или несколько рабочих потоков должны удалить элементы из этого списка для выполнения задач. Это должно быть защищено замком. Таким образом, нужно также запереть замок.

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

ОБНОВЛЕНИЕ: Далее в руководстве подразумевается, что есть что-то, о чем я не знаю: «задача очереди не требует захвата в ядро ​​для получения мьютекса».

Как это работает?

+0

Это может быть интересно: http: // stackoverflow.ком/вопросы/17599401/какой-преимущества-делает-диспетчерская-синхронизация уже поверх синхронизируется. –

ответ

0

Существуют блокировки без очередей. Одной из причин, по которым они часто бывают pooh-poohed, является то, что они являются специфичными для платформы, поскольку они полагаются на атомарные операции процессоров (например, приращение, декремент, сравнение и своп и т. Д.), И их точное внедрение будет варьироваться от одной архитектуры процессора до другой. Поскольку Apple является и поставщиком ОС, и аппаратным обеспечением, эта критика гораздо меньше относится к платформам Apple.

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

Для получения дополнительной информации об одной из возможных реализаций очереди MacOS/IOS блокировки бесплатно, прочитать here об этих функциях:

void OSAtomicEnqueue(OSQueueHead *__list, void *__new, size_t __offset); 
void* OSAtomicDequeue(OSQueueHead *__list, size_t __offset); 

Стоит отметить здесь, что НОД был (в основном) с открытым исходным кодом, так что если вы «Поистине любопытно, как реализовать его очереди, идем дальше и use the source, Люк.

+1

FWIW OSAtomicEnqueue/OSAtomicDequeue - это не то, что GCD использует внутри, что API реализует незащищенную очередь LIFO (стек), тогда как очереди GCD реализуются с помощью алгоритма очереди FIFO без блокировки. – das

+1

Yup. Я просто указываю, что существуют блокирующие реализации очередей, и что источник GCD доступен. Материал OSAtomic * - это всего лишь одна реализация, которую легко найти в доказательстве этой точки. – ipmcc

2

В настоящее время выпуски OS X и iOS, как мьютексы pthread, так и GCD-очереди (а также семафоры GCD) реализованы исключительно в пользовательском пространстве без необходимости ловушки в ядро, за исключением случаев, когда есть конфликт (то есть блокировка потока в ядро ждет «разблокировки»).

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

Если вы просто заменить замки с призывами dispatch_sync вы на самом деле не в полной мере использовать особенности НОД (хотя реализация dispatch_sync случается немного более эффективным, главным образом из-за PTHREAD семафоров, имеющих для удовлетворения дополнительных ограничений).