iOS - TLS(线程本地存储)

从源码中,详细总结 TLS (Thread Local Storage) 的实现:

1. TLS 基本结构

objectivec 复制代码
// TLS 的基本结构
struct tls_data {
    pthread_key_t key;           // 线程本地存储的键
    void (*destructor)(void *);  // 清理函数
};

// 自动释放池的 TLS
class AutoreleasePoolPage {
    static pthread_key_t const key = AUTORELEASE_POOL_KEY;  // TLS key
    static pthread_key_t key;                               // 实际的 key
};

2. TLS 初始化

objectivec 复制代码
void tls_init(void) {
    // 1. 创建线程键
    _objc_pthread_key = pthread_key_create(&_objc_pthread_destroyspecific);
    
    // 2. 初始化主线程的 TLS
    pthread_setspecific(_objc_pthread_key, &_objc_main_thread);
    
    // 3. 初始化自动释放池的 key
    AutoreleasePoolPage::key = tls_create(&_objc_autoreleasepool_deallocate);
}

3. TLS 操作函数

objectivec 复制代码
// 1. 创建 TLS key
static pthread_key_t tls_create(void (*destructor)(void*)) {
    pthread_key_t key;
    int result = pthread_key_create(&key, destructor);
    if (result != 0) {
        _objc_fatal("pthread_key_create failed (%d)", result);
    }
    return key;
}

// 2. 获取 TLS 值
static inline void *tls_get(pthread_key_t key) {
    return pthread_getspecific(key);
}

// 3. 设置 TLS 值
static inline void tls_set(pthread_key_t key, void *value) {
    pthread_setspecific(key, value);
}

4. TLS 清理机制

objectivec 复制代码
// TLS 数据清理
static void tls_dealloc(void *p) {
    // 1. 检查占位符
    if (p == (void*)EMPTY_POOL_PLACEHOLDER) {
        return;
    }
    
    // 2. 清理自动释放池页面
    AutoreleasePoolPage *page = (AutoreleasePoolPage *)p;
    
    // 3. 验证页面完整性
    if (page->child) {
        _objc_fatal("thread-local storage corrupted");
    }
    
    if (page->parent) {
        _objc_fatal("thread-local storage corrupted");
    }
    
    // 4. 销毁页面
    page->kill();
}

5. TLS 在自动释放池中的应用

objectivec 复制代码
class AutoreleasePoolPage {
    // 1. 获取当前线程的热页面
    static inline AutoreleasePoolPage *hotPage() {
        AutoreleasePoolPage *result = (AutoreleasePoolPage *)
            tls_get_direct(key);
        if (result) result->fastcheck();
        return result;
    }
    
    // 2. 设置热页面
    static inline void setHotPage(AutoreleasePoolPage *page) {
        if (page) page->fastcheck();
        tls_set_direct(key, (void *)page);
    }
};

6. TLS 性能优化

objectivec 复制代码
// 1. 直接访问优化
static inline void *tls_get_direct(pthread_key_t key) {
    // 直接从线程本地存储获取数据
    return _pthread_getspecific_direct(key);
}

// 2. 快速检查
void fastcheck() {
#if FASTAUTORELEASEPOOL_SPIN_DEBUG
    // 仅在调试模式下执行完整检查
    check(false);
#else
    // 生产环境只做基本检查
    if (!magic) _objc_fatal("bad magic");
#endif
}

7. TLS 线程安全

objectivec 复制代码
// 1. 线程安全的访问
void *getSpecific() {
    // pthread_getspecific 是线程安全的
    return pthread_getspecific(key);
}

// 2. 线程检查
void check(bool die) {
    // 确保在正确的线程上操作
    if (thread != pthread_self()) {
        if (die) _objc_fatal("thread mismatch");
    }
}

8. TLS 使用场景

objectivec 复制代码
// 1. 自动释放池管理
static inline void *autoreleaseFast(id obj) {
    AutoreleasePoolPage *page = hotPage();
    if (page && !page->full()) {
        return page->add(obj);
    }
    return autoreleaseFullPage(obj);
}

// 2. 线程特定数据
static void setThreadSpecific(id value) {
    tls_set(_objc_pthread_key, value);
}

总结要点:

  1. 基本特性:
  • 线程私有存储
  • 键值对管理
  • 自动清理机制
  1. 性能考虑:
  • 直接访问优化
  • 快速路径
  • 内存效率
  1. 安全性:
  • 线程隔离
  • 数据保护
  • 完整性检查
  1. 应用场景:
  • 自动释放池
  • 线程本地缓存
  • 线程特定数据
  1. 注意事项:
  • 内存管理
  • 线程安全
  • 性能优化
  • 清理时机
相关推荐
qq_4298796728 分钟前
省略号和可变参数模板
开发语言·c++·算法
优秀的颜1 小时前
计算机基础知识(第五篇)
java·开发语言·分布式
CodeWithMe1 小时前
【C/C++】std::vector成员函数清单
开发语言·c++
uyeonashi1 小时前
【QT控件】输入类控件详解
开发语言·c++·qt
iCxhust3 小时前
Prj10--8088单板机C语言8259测试(1)
c语言·开发语言
крон5 小时前
【Auto.js例程】华为备忘录导出到其他手机
开发语言·javascript·智能手机
zh_xuan6 小时前
c++ 单例模式
开发语言·c++·单例模式
老胖闲聊6 小时前
Python Copilot【代码辅助工具】 简介
开发语言·python·copilot
Blossom.1187 小时前
使用Python和Scikit-Learn实现机器学习模型调优
开发语言·人工智能·python·深度学习·目标检测·机器学习·scikit-learn
I烟雨云渊T7 小时前
iOS 门店营收表格功能的实现
ios