在iOS开发中,多线程安全是关键问题,锁机制用于保护临界区资源。以下是常见的锁机制、示例及原理分析:
1. NSLock(互斥锁)
-
原理:基于
pthread_mutex的封装,非递归锁。线程在获取锁失败时会休眠,等待唤醒。 -
Objective-C:
NSLock *lock = [[NSLock alloc] init]; [lock lock]; // 临界区代码 [lock unlock]; -
Swift:
let lock = NSLock() lock.lock() defer { lock.unlock() } // 临界区代码
2. @synchronized
-
原理:基于
objc_sync_enter和objc_sync_exit的递归锁,以传入对象为锁标识。 -
Objective-C:
@synchronized(self) { // 临界区代码 } -
Swift(需手动调用):
objc_sync_enter(self) defer { objc_sync_exit(self) } // 临界区代码
3. DispatchSemaphore(信号量)
-
原理:通过计数器控制访问,
wait()减1,signal()加1,计数器为0时阻塞。 -
Objective-C:
dispatch_semaphore_t semaphore = dispatch_semaphore_create(1); dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); // 临界区代码 dispatch_semaphore_signal(semaphore); -
Swift:
let semaphore = DispatchSemaphore(value: 1) semaphore.wait() defer { semaphore.signal() } // 临界区代码
4. os_unfair_lock(替代OSSpinLock)
-
原理:低级锁,解决优先级反转问题,需手动管理,不可递归。
-
Objective-C:
#import <os/lock.h> os_unfair_lock lock = OS_UNFAIR_LOCK_INIT; os_unfair_lock_lock(&lock); // 临界区代码 os_unfair_lock_unlock(&lock); -
Swift:
var lock = os_unfair_lock() os_unfair_lock_lock(&lock) defer { os_unfair_lock_unlock(&lock) } // 临界区代码
5. pthread_mutex(POSIX互斥锁)
-
原理:跨平台互斥锁,支持配置递归属性。
-
Objective-C:
pthread_mutex_t mutex; pthread_mutex_init(&mutex, NULL); pthread_mutex_lock(&mutex); // 临界区代码 pthread_mutex_unlock(&mutex); pthread_mutex_destroy(&mutex); -
Swift(需桥接或使用C API)。
6. NSRecursiveLock(递归锁)
-
原理:允许同一线程多次加锁,避免死锁。
-
Objective-C:
NSRecursiveLock *lock = [[NSRecursiveLock alloc] init]; [lock lock]; [lock lock]; // 重复加锁 // 临界区代码 [lock unlock]; [lock unlock]; -
Swift:
let lock = NSRecursiveLock() lock.lock() defer { lock.unlock() } // 可重复加锁
7. NSCondition(条件锁)
-
原理:结合锁和条件变量,用于线程间通信。
-
Objective-C:
NSCondition *condition = [[NSCondition alloc] init]; [condition lock]; while (!ready) [condition wait]; // 执行操作 [condition unlock]; -
Swift:
let condition = NSCondition() condition.lock() defer { condition.unlock() } while !ready { condition.wait() } // 执行操作
锁的选择与性能
- 性能排序:
os_unfair_lock>pthread_mutex>NSLock>@synchronized。 - 自旋锁:
OSSpinLock因优先级反转被弃用,改用os_unfair_lock。 - 递归需求:使用
NSRecursiveLock或配置pthread_mutex为递归属性。 - 线程通信:使用
NSCondition或DispatchSemaphore。
注意事项
- 避免在锁内调用外部代码,防止死锁。
- 确保加锁和解锁成对出现,使用
defer(Swift)保证解锁。 - 不要跨线程解锁
os_unfair_lock,可能导致崩溃。
通过合理选择锁机制,可提升多线程安全性和性能。