从源码中,详细总结 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. 注意事项:
- 内存管理
- 线程安全
- 性能优化
- 清理时机