В чем разница (преимущество и недостаток) между использованием DispatchGroup и NSRecursiveLock?

В чем разница (преимущество и недостаток) между использованием DispatchGroup и NSRecursiveLock?

Похоже, они делают то же самое.


person Dmitry    schedule 25.09.2019    source источник
comment
См. stackoverflow.com/questions/35906568/, а затем решают, делает ли NSLock то же самое.   -  person rmaddy    schedule 25.09.2019
comment


Ответы (2)


Блокировки и группы служат совершенно разным целям. При работе с рядом параллельных задач:

  • Блокировка обычно используется для предотвращения/блокировки этих задач от одновременного взаимодействия с некоторым общим ресурсом, не ориентированным на многопотоковое исполнение.

  • Группа обычно используется для определения того, когда все эти параллельные задачи завершены (независимо от порядка их завершения).

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

person Rob    schedule 26.09.2019
comment
К вашему сведению, я не вникал в различие NSLock (исходный вопрос) и NSRecursiveLock, так как оно не кажется уместным при обсуждении блокировок и групп. Разница между этими двумя типами блокировок заключается в том, что один позволяет данному потоку рекурсивно блокироваться, а другой — нет. Но с точки зрения координации между потоками они функционально одинаковы. Но если у вас есть вопросы, касающиеся рекурсивных блокировок, а не нерекурсивных, дайте мне знать. - person Rob; 26.09.2019
comment
Риск прослыть троллем: не используйте рекурсивные блокировки. Они анти-паттерн. :) - person ipmcc; 27.09.2019
comment
@ipmcc - Не беспокойтесь. Я не защищаю рекурсивные блокировки, а просто поясняю, почему я избегал их в своем ответе. Но по какой-то причине вопрос был явно изменен с NSLock на NSRecursiveLock, возможно, в ответ на ваши замечания «или даже в той же теме». (Кстати, Дмитрий, неуместно изменять вопрос таким образом, чтобы он аннулировал существующие ответы.) Что касается правильности рекурсивных блокировок, они не являются анти-шаблоном, ИМХО, поскольку они являются правильным инструментом для определенных, узких случаев, но, да, они могут быть неправильно использованы как неуклюжие обходные пути для неаккуратного кода блокировки, и, как таковые, часто являются запахом кода. - person Rob; 27.09.2019

Основное отличие состоит в том, что DispatchGroup ближе к счетному семафору с обратным вызовом, тогда как NSLock является простым мьютексом.

Например, DispatchGroup может быть enter обработано более одного раза одним или несколькими потоками, а enterобработка DispatchGroup никогда не заблокирует вызывающий поток. Вызывающие потоки также отвечают за уравновешивание каждого вызова enter вызовом leave. Если в группе зарегистрирован обратный вызов notify, он будет выполняться, когда количество enters минус количество leaves достигнет 0. Хорошим примером использования DispatchGroup может быть выполнение нескольких сетевых запросов и наличие одного фрагмента кода обратного вызова. выполняется после того, как все сетевые запросы завершены (или истекло время ожидания и т. д.).

Однако, если один поток lock получает NSLock, любой другой поток (или даже тот же самый поток, если уж на то пошло) пытается снова lock выполнить его до того, как он будет unlocked, второй поток будет заблокирован до тех пор, пока не будет unlocked (и, возможно, никогда, если вы попробуйте lock дважды lock из одной и той же темы). Хорошим примером использования NSLock является предоставление многопоточного доступа к одному изменяемому элементу данных. В этом случае несколько потоков могут быть уверены, что будут выполнять согласованные операции чтения и записи в/из изменяемого хранилища без потенциального вытеснения друг друга.

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

person ipmcc    schedule 25.09.2019