当前位置: 首页 > article >正文

iOS - TLS(线程本地存储)

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

1. TLS 基本结构

// 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 初始化

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 操作函数

// 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 清理机制

// 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 在自动释放池中的应用

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 性能优化

// 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 线程安全

// 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 使用场景

// 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. 基本特性:

  • 线程私有存储
  • 键值对管理
  • 自动清理机制

2. 性能考虑:

  • 直接访问优化
  • 快速路径
  • 内存效率

3. 安全性:

  • 线程隔离
  • 数据保护
  • 完整性检查

4. 应用场景:

  • 自动释放池
  • 线程本地缓存
  • 线程特定数据

5. 注意事项:

  • 内存管理
  • 线程安全
  • 性能优化
  • 清理时机

http://www.kler.cn/a/504944.html

相关文章:

  • 代码随想录算法训练营第十二天|第18题. 四数之和
  • 计算机视觉与深度学习:使用深度学习训练基于视觉的车辆检测器(MATLAB源码-Faster R-CNN)
  • 【WEB】网络传输中的信息安全 - 加密、签名、数字证书与HTTPS
  • PHP 字符串
  • LLM实现视频切片合成 前沿知识调研
  • Android SystemUI——使用Dagger2加载组件(四)
  • 40,【5】CTFHUB WEB SQL 时间盲注
  • 跨境電商防關聯指紋流覽器Linken Sphere使用教程
  • vscode配置opencv4.8环境
  • Open FPV VTX开源之嵌入式OSD配置
  • extends配置项详解
  • 深度学习中的模块复用原则(定义一次还是多次)
  • C语言数据结构编程练习-用指针创建顺序表,进行创销和增删改查操作
  • 屏幕轻触间:触摸交互从 “感知” 到 “智算” 的隐秘路径
  • 爬虫案例:python爬取京东商品数据||京东商品详情SKU价格
  • OpenSeaOtter使用手册-项目简介
  • # MyBatis 基础了解
  • camera 配置预览和拍照streams上报的可用尺寸列表
  • DevOps实用场景:在哪些业务中应用DevOps最有效
  • selenium操作指南,2万字总结
  • 【力扣Hot100】双指针
  • Linux磁盘存储与内存管理命令
  • 【C++学习篇】红黑树 从入门到进阶
  • Vue 开发者的 React 实战指南:表单处理篇
  • 微信小程序:跨页面数据修改全攻略
  • Web前端------HTML块级和行内标签之行内标签