Locks, Thread Safety, and Swift: 2017 Edition
Note that
pthread_mutex_t,pthread_rwlock_t, andos_unfair_lockare value types, not reference types. That means that if you use=on them, you make a copy. This is important, because these types can’t be copied! If you copy one of thepthreadtypes, the copy will be unusable and may crash when you try to use it. Thepthreadfunctions that work with these types assume that the values are at the same memory addresses as where they were initialized, and putting them somewhere else afterwards is a bad idea.os_unfair_lockwon’t crash, but you get a completely separate lock out of it which is never what you want.If you use these types, you must be careful never to copy them, whether explicitly with a
=operator, or implicitly by, for example, embedding them in astructor capturing them in a closure.Additionally, since locks are inherently mutable objects, this means you need to declare them with
varinstead oflet.[…]
You must be careful with the
pthreadlocks, because you can create a value using the empty()initializer, but that value won’t be a valid lock. These locks must be separately initialized usingpthread_mutex_initorpthread_rwlock_init[…]
Previously: Locks, Thread Safety, and Swift, OSSpinLock Is Unsafe, os_unfair_lock.
Update (2018-07-31): Vadim Bulavin (via Andy Bargh):
In this article we will benchmark performance of most notable Apple locking APIs and suggest best options based on their characteristics.
[…]
Based on the benchmark results,
DispatchQueuemust be your best choice for creating a critical section in your code.Under 10000 calculations it performs almost identical to locks, while providing higher-level and thus less error-prone API.