Monday, October 30, 2017

Locks, Thread Safety, and Swift: 2017 Edition

Mike Ash:

Note that pthread_mutex_t, pthread_rwlock_t, and os_unfair_lock are 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 the pthread types, the copy will be unusable and may crash when you try to use it. The pthread functions 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_lock won'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 a struct or capturing them in a closure.

Additionally, since locks are inherently mutable objects, this means you need to declare them with var instead of let.

[…]

You must be careful with the pthread locks, 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 using pthread_mutex_init or pthread_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, DispatchQueue must 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.

Comments RSS · Twitter

Leave a Comment