摘要
线程局部存储(Thread Local Storage), 简称TLS,提供了一种存储线程私有数据的方式,每个线程的私有数据对其他线程均不可见。Chromium是一个多进程多线程架构的浏览器,运行时会创建多达30几个线程,其中很多线程需要拥有自己私有数据,在TLS数量有限的系统上,例如Android 4.3或更早的系统,可能会因为无法分配足够的TLS而导致Chromium崩溃。本文将介绍最近在Chromium提交代码中是如何解决这个问题的。
TLS在Chromium中的使用
Chromium代码中,有些类提供了一个current()方法用来返回调用线程的私有数据,最典型的两个例子是MessageLoop和RenderThread。以MessageLoop为例,因为每个线程可能运行着一个主消息循环,如何能够获取与线程相关的主消息循环呢?为此,MessageLoop提供了current()方法,当线程在创建MessageLoop实例时,会将这个实例设置为线程的私有数据,当调用current()方法时,再将这个私有数据返回给调用者。
每个TLS槽都由一个唯一的键值(key)标识,这个键值由进程负责向OS申请分配,如果当前进程申请的键值数量超过系统规定的上限,申请将失败,即无法获取一个新的TLS槽。线程可以将TLS槽绑定到一个私有数据上,这个私有数据实际上是一个指针,指向一块由调用线程动态分配的内存块。
Chromium代码中,对TLS的使用都抽象在ThreadLocalPointer模板类中(参见base/threading/thread_local.h文件):
te