iOS - 自旋锁

在 Objective-C 运行时中大量使用自旋锁,主要有以下几个原因:

1. 性能考虑

上下文切换成本

objectivec 复制代码
// 自旋锁实现
static ALWAYS_INLINE void OSSpinLockLock(volatile OSSpinLock *lock) {
    do {
        while (lock->value != 0) {
            __asm__ volatile ("pause");  // 不释放CPU,继续尝试
        }
    } while (!OSAtomicCompareAndSwap32(0, 1, &lock->value));
}

// 相比互斥锁的实现
pthread_mutex_lock(&mutex);   // 可能导致线程休眠和上下文切换
// ... 
pthread_mutex_unlock(&mutex);

优势:

  1. 避免了线程上下文切换的开销
  2. 适合短期持有的场景
  3. 在多核处理器上效率更高

2. 使用场景特点

短暂的临界区

objectivec 复制代码
// 属性访问的典型场景
id objc_getProperty(id self, SEL _cmd, ptrdiff_t offset, BOOL atomic) {
    if (!atomic) return *((id *)((char *)self + offset));
    
    spinlock_t& slotlock = PropertyLocks[GOODHASH(offset)];
    slotlock.lock();    // 持锁时间极短
    id value = *((id *)((char *)self + offset));
    slotlock.unlock();
    return value;
}

特点:

  1. 锁的持有时间非常短
  2. 竞争不激烈
  3. 代码路径简单

3. 内存效率

结构简单

objectivec 复制代码
typedef struct {
    volatile int32_t value;  // 仅需要一个32位整数
} OSSpinLock;

// 相比互斥锁的复杂结构
struct pthread_mutex_t {
    // ... 更复杂的内部结构
    // 包含条件变量、等待队列等
};

优势:

  1. 内存占用小
  2. 缓存友好
  3. 初始化成本低

4. 适用的情况

理想场景

objectivec 复制代码
// 引用计数操作
inline bool objc_object::sidetable_tryRetain() {
    SideTable& table = SideTables()[this];
    bool result = false;
    
    table.lock();   // 快速的加锁解锁
    // 简单的引用计数操作
    table.unlock();
    
    return result;
}

最佳实践:

  1. 临界区执行时间短
  2. 线程等待时间短
  3. CPU资源充足

5. 潜在问题

优先级反转

objectivec 复制代码
// 可能出现的问题场景
while (lock->value != 0) {
    // 如果持有锁的是低优先级线程
    // 而等待的是高优先级线程
    // 可能导致优先级反转
    __asm__ volatile ("pause");
}

解决方案:

  1. iOS 10 后系统更多使用 os_unfair_lock
  2. 对于复杂场景使用互斥锁
  3. 需要考虑优先级时使用其他锁机制

6. 使用建议

适合使用自旋锁的场景

objectivec 复制代码
// 1. 简单的原子操作
atomic_property.lock();
value = _property;
atomic_property.unlock();

// 2. 快速的引用计数操作
spinlock.lock();
refCount++;
spinlock.unlock();

不适合使用自旋锁的场景

objectivec 复制代码
// 1. 复杂的操作
lock.lock();
[self complexOperation];  // 耗时操作
lock.unlock();

// 2. 可能阻塞的操作
lock.lock();
[self operationMayBlock];  // 可能阻塞
lock.unlock();

7. 总结

自旋锁在 Objective-C 运行时中的广泛使用是基于以下考虑:

  1. 性能优化:避免上下文切换
  2. 场景匹配:适合短期、快速的操作
  3. 资源效率:内存占用小,初始化快
  4. 实现简单:容易维护和调试
  5. 硬件友好:在现代多核处理器上表现良好

但需要注意:

  • 不适合长时间持有
  • 要考虑优先级反转问题
  • iOS 10 后推荐使用 os_unfair_lock
  • 复杂场景应考虑其他锁机制
相关推荐
wahkim3 小时前
移动端开发工具集锦
flutter·ios·android studio·swift
2501_916007474 小时前
提升 iOS 26 系统流畅度的实战指南,多工具组合监控
android·macos·ios·小程序·uni-app·cocoa·iphone
hellojackjiang20115 小时前
全面适配iOS 26液态玻璃,基于开源IM即时通讯框架MobileIMSDK:RainbowChat-iOS端v10.2发布
ios·网络编程·即时通讯·im开发·rainbowchat
非专业程序员Ping9 小时前
一文读懂字符、字形、字体
ios·swift·font
2501_9159214310 小时前
iOS 应用代上架流程,多工具组合与使用 开心上架 跨平台自动化上传指南
android·ios·小程序·uni-app·自动化·cocoa·iphone
日日行不惧千万里10 小时前
2025最新仿默往 IM 即时通讯系统源码(PC + Web + iOS + Android)完整版发布!
android·ios
歪歪10010 小时前
React Native开发Android&IOS流程完整指南
android·开发语言·前端·react native·ios·前端框架
阿里超级工程师11 小时前
ios云打包证书申请不需要苹果电脑也是可以的
ios·证书·云打包
2501_9159184113 小时前
iOS 混淆与 IPA 加固一页式行动手册(多工具组合实战 源码成品运维闭环)
android·运维·ios·小程序·uni-app·iphone·webview
RollingPin16 小时前
iOS八股文之 网络
网络·网络协议·ios·https·udp·tcp·ios面试