Что значит для чего-то поточно-ориентированного в iOS?
Я часто сталкиваюсь с ключевыми терминами "потокобезопасность" и удивляюсь, что это значит. Например, в Firebase или Realm некоторые объекты считаются "потокобезопасными". Что именно означает, что что-то является потокобезопасным?
5 ответов
Thread-Unsafe -> Если какой-либо объект позволяет изменять более чем один поток одновременно. Потокобезопасный -> Если какой-либо объект не позволяет изменять более чем одному потоку одновременно. Неизменяемые объекты обычно являются поточно-ориентированными
Объект называется потокобезопасным, если несколько потоков могут вызывать методы или получать доступ к данным члена объекта без каких-либо проблем; "проблема" в широком смысле определяется как отклонение от поведения, когда доступ осуществляется только из одного потока.
Например, объект, который содержит код i = i + 1
для обычного целого числа i
не будет потокобезопасным, так как два потока могут встретить этот оператор, а один поток может прочитать исходное значение i
, увеличьте его, затем запишите это единственное увеличенное значение; все одновременно как другая нить. Таким образом, i
будет увеличен только один раз, где он должен быть увеличен в два раза.
После поиска ответа, я получил следующее с этого сайта:
Поточно-безопасный код можно безопасно вызывать из нескольких потоков или одновременных задач, не вызывая проблем (повреждение данных, сбой и т. Д.). Код, который не является потокобезопасным, должен выполняться одновременно только в одном контексте. Примером потокаобезопасного кода является let a = ["thread-safe"]. Этот массив только для чтения, и вы можете использовать его из нескольких потоков одновременно без проблем. С другой стороны, массив, объявленный с помощью var a = ["thread-unsafe"], является изменяемым и может быть изменен. Это означает, что он не является потокобезопасным, поскольку несколько потоков могут одновременно обращаться к массиву и изменять его с непредсказуемыми результатами. Переменные и структуры данных, которые являются изменяемыми и не являются поточно-ориентированными, должны быть доступны только из одного потока за раз.
Thread safe
means that your program works as expected. It is about multithreading envirompment, where we have a problem with
shared resource
. Which in turn creates:
Atomicity, Visibility, Ordering
<sup>[About]</sup>
Apple provides us by
Synchronization Tools
:
Atomicity
-
Atomic Operations
- lock free mechanism which is based on hardware instructions - for example Compare-And-Swap(CAS) <sup>[More]</sup>...- Objective-C
OSAtomic...
- [Swift Atomic Operations]
- Objective-C
Visibility
-
Volatile Variable
- read value from memory(no cache)- Objective-C volatile
Ordering
-
Memory Barriers
- guarantees up-to date data <sup>[About]</sup>- Objective-C OSMemoryBarrier
synchronization tools
Locks
- thread can get a lock and nobody else access to the resource.NSLock
.- consists of Threads queue, Counter value and has
wait()
andsignal()
api. allows a number of threads(Counter value) work with resource at a given moment.DispatchSemaphore
-
Mutex
- mutual exclusion, mutually exclusive - is a type ofSemaphore
(allows several threads) where Thread can acquire it and is able to work with block as a single encroacher, all others thread will be blocked until release. The main different withlock
is thatmutex
also works between processes(not only threads). Also it includesmemory barrier
.POSIX Mutex Lock
, Objective-C@synchronized
-
Recursive lock
-Lock Reentrance
- thread can acquire a lock several times.NSRecursiveLock
-
Spin lock
- waiting thread checks if it can get a lock repeatedly based on polling mechanism. It is useful for small operation. In this case thread is not blocked and expensive operations like context switch is not nedded
- consists of Threads queue, Counter value and has
Operations
Приведу простой пример. Если что-то совместно используется несколькими потоками без каких-либо проблем, таких как сбой, это потокобезопасно. Например, если у вас есть константа (let value = ["Facebook"]) и она используется в нескольких потоках, она является потокобезопасной, поскольку предназначена только для чтения и не может быть изменена. Принимая во внимание, что если у вас есть переменная (var value = ["Facebook"]) , это может вызвать потенциальный сбой или потерю данных при совместном использовании с несколькими потоками, потому что эти данные могут быть изменены.