#objective-c #multithreading #ios #thread-safety
#objective-c #многопоточность #iOS #безопасность потоков
Вопрос:
У меня есть приложение, которому необходимо отправлять собранные данные каждые X миллисекунд (и НЕ раньше!). Моей первой мыслью было собрать данные в NSMutableArray
( array1
) на thread1
. По thread2
истечении X миллисекунд ожидания, он заменит NSMutableArray на новый ( array2
) и затем обработает его содержимое. Однако я не хочу thread1
вносить дальнейшие изменения, array1
как только thread2
они появятся.
Вероятно, это сработает, но потокобезопасность — это не та область, где вы хотите «просто попробовать это». Каковы подводные камни этого подхода и что я должен сделать вместо этого?
(Кроме того, если thread2
на самом деле это экземпляр NSTimer, как меняется проблема / ответ? Будет ли все это происходить в одном потоке [что было бы хорошо для меня, поскольку обработка занимает крошечную долю миллисекунды]?).
Ответ №1:
Вам следует использовать либо NSOperationQueue, либо Grand Central Dispatch. По сути, вы создадите операцию, которая получает ваши данные и загружает их по истечении X миллисекунд. Каждая операция будет независимой, и вы можете настроить очередь в зависимости от того, сколько одновременных операций вы разрешаете, приоритет операций и т.д.
Документы Apple по параллелизму должны помочь:
Ответ №2:
Подводные камни этого подхода связаны с тем, что вы «заменяете» NSArray
на новую. Представьте, что thread1 получает ссылку на массив, и в то же время thread2 меняет местами массивы и завершает обработку. Thread1 теперь выполняет запись в мертвый массив (тот, который больше не будет обрабатываться), даже если это всего на несколько миллисекунд. Способ предотвратить это, конечно, заключается в использовании синхронизированных блоков кода (т. Е. сделать ваш код «потокобезопасным») в критических разделах, но довольно сложно не превысить отметку и синхронизировать слишком большую часть вашего кода (жертвуя производительностью).
Таким образом, риски заключаются в том, что вы будете:
- Создайте код, который не является потокобезопасным
- Создайте код, который злоупотребляет синхронизацией и работает медленно (а потоки уже имеют издержки производительности)
- Создайте какую-нибудь комбинацию из этих двух: медленный, небезопасный код.
Идея состоит в том, чтобы «перейти от потоков», о чем и эта ссылка.