Многопоточность — это механизм, позволяющий процессору одновременно (или «условно-одновременно») работать над решением нескольких задач.
Выделяют два типа многопоточности:
Многопоточность следует использовать тогда, когда в процессе работы программы могут быть выделены несколько частей, каждая из которых может выполняться независимо от других.
К примеру, если некоторое приложение имеет графический интерфейс, и при этом оно решает «тяжелую» задачу математических расчетов, то имеет смысл разделить отображение интерфейса и выполнение данной задачи по разным потокам, чтобы интерфейс продолжал оставаться плавным, а (в случае наличия нескольких ядер) задача исполнялась максимально быстро.
Context Switching — это механизм переключения между активными потоками. При этом один поток приостанавливается, вся информация о его состоянии сохраняется, после чего загружается информация о состоянии другого потока, после чего он начинает/продолжает функционировать, и так далее по кругу.
Условно говоря, процесс — это экземпляр запущенного приложения, совокупность кода и данных. У него собственное виртуальное адресное пространство. Разные процессы не имеют прямого доступа к памяти друг друга. Для их взаимного обмена данными необходимо использовать различные способы, вроде файлов, сокетов, портов и т.д.
Поток — это минимальная единица исполнения кода, набор инструкций. В рамках процесса создается один или несколько потоков. У каждого потока есть собственный стек (stack) в памяти, но все потоки в рамках одного процесса работают с общей кучей (heap).
Изначально, после запуска процесса в нем существует всего один поток — главный поток. Если самостоятельно не предусмотреть механизмы многопоточности в приложении, то все инструкции будут исполняться на главном потоке.
Главный поток появляется вместе с запуском приложения и прекращает свою работу одновременно с завершением работы приложения. Он является родительским для всех остальных потоков в рамках процесса.
pthreads
— низкоуровневая реализация многопоточности.Thread
.Grand Central Dispatch
.Operations
.Tasks
(начиная со Swift 5.5).@MainActor
(начиная со Swift 5.5).Атомарной называется такая операция, которая не может быть разделена на более мелкие. Она либо исполняется полностью, либо не исполняется совсем.
Атомарная операция является потокобезопасной. Это значит, что в процессе ее выполнения другие потоки не смогут каким-либо образом влиять на используемые в процессе операции ресурсы. То есть при выполнении атомарной операции нет необходимости использовать механизмы синхронизации.
В общем случае, синхронизация служит для согласования действий нескольких потоков и обеспечения консистентности общих для них данных. Говоря иначе, с помощью средств синхронизации можно определить правила взаимодействия потоков и обеспечить их корректную взаимную работу.
Основные наиболее используемые элементы:
NSLock
, NSConditionLock
, NSDistributedLock
.NSCondition
.DispatchSemaphore
.Grand Central Dispatch
.Так же можно упомянуть:
pthread_mutex_t
— мьютекс для с-шной реализации работы с потоками (pthread_t
).pthread_rwlock_t
.pthread_cond_t
.unfair lock
.objc_sync
.
Объект удаляется на том же потоке, где произошел последний release, то есть на том потоке, на котором счетчик ссылок стал равен нулю.