android::Thread
是 Android libutils
库中的 轻量级 C++ 线程封装,主要用于 Native 层的多线程管理,在 AudioFlinger、SurfaceFlinger、Camera HAL 等组件中广泛使用。
- 基于
pthread
进行封装,提供 C++ 线程管理能力。 - 支持
run()
方式启动线程,无需手动调用pthread_create
。 - 通过
threadLoop()
实现任务循环,适用于长时间运行的任务。 - 提供
requestExit()
进行优雅退出,避免pthread_cancel()
造成资源泄露。 - 继承
RefBase
,支持sp<>
智能指针管理线程生命周期。
android::Thread 的使用
1. 继承 android::Thread
创建自定义线程
覆写 threadLoop 虚函数 ,返回 true 表示继续循环,false 表示退出线程 ,还需要注意保持android::Thread 对象存活,如果被回收 ,threadLoop 函数即使返回 true ,线程也会退出
cpp
#include <utils/Thread.h>
#include <utils/Log.h>
using namespace android;
class MyThread : public Thread {
public:
MyThread() {}
virtual ~MyThread() {}
virtual bool threadLoop() override {
ALOGI("Thread running...");
sleep(1); // 模拟任务
return true;
}
};
2. 启动线程
cpp
sp<MyThread> myThread = new MyThread();
myThread->run("MyWorkerThread"); // 线程启动
3. 请求线程退出
cpp
myThread->requestExit(); // 仅标记退出
myThread->join(); // 等待线程真正退出
源码分析
android::Thread
构造函数
cpp
explicit Thread(bool canCallJava = true);
// canCallJava 默认为 true
Thread::Thread(bool canCallJava)
: mCanCallJava(canCallJava),
mThread(thread_id_t(-1)),
mLock("Thread::mLock"),
mStatus(OK),
mExitPending(false),
mRunning(false),
mTid(-1)
{
}
// run 方法
// name : 线程名字
// priority : 线程优先级 ,默认 PRIORITY_DEFAULT
// stack : 线程栈大小 ,默认为 0
virtual status_t run(const char* name,
int32_t priority = PRIORITY_DEFAULT,
size_t stack = 0);
status_t Thread::run(const char* name, int32_t priority, size_t stack)
{
LOG_ALWAYS_FATAL_IF(name == nullptr, "thread name not provided to Thread::run");
Mutex::Autolock _l(mLock);
// mRunning 默认为 false ,只能调用一次 run 方法
if (mRunning) {
// thread already started
return INVALID_OPERATION;
}
mStatus = OK;
mExitPending = false;
mThread = thread_id_t(-1);
// 自己持有自己的强引用
mHoldSelf = sp<Thread>::fromExisting(this);
mRunning = true;
bool res;
// mCanCallJava 默认为 true ,调用 createThreadEtc 创建线程
if (mCanCallJava) {
// _threadLoop 函数指针,线程启动要执行的函数
res = createThreadEtc(_threadLoop,
this, name, priority, stack, &mThread);
} else {
res = androidCreateRawThreadEtc(_threadLoop,
this, name, priority, stack, &mThread);
}
// 如果线程启动失败
if (res == false) {
mStatus = UNKNOWN_ERROR;
mRunning = false;
mThread = thread_id_t(-1);
mHoldSelf.clear(); // 移除自身引用,让 thread 对象可以回收
return UNKNOWN_ERROR; // 返回错误
}
return OK;
}
// entryFunction : 为函数指针 _threadLoop 线程入口函数
// userData : 线程函数的的参数 ,传递的是 android::Thread this 指针
// name : 为线程名字 ,默认为 android:unnamed_thread
// threadPriority : 线程优先级
// threadStackSize : 线程栈空间大小,默认为 0
// threadId : 线程 id ,默认为 nullptr 传递的是 android::Thread 成员变量 mThread
inline bool createThreadEtc(thread_func_t entryFunction,
void *userData,
const char* threadName = "android:unnamed_thread",
int32_t threadPriority = PRIORITY_DEFAULT,
size_t threadStackSize = 0,
thread_id_t *threadId = nullptr)
{
return androidCreateThreadEtc(entryFunction, userData, threadName,
threadPriority, threadStackSize, threadId) ? true : false;
}
// androidCreateThreadEtc 调用 gCreateThreadFn 函数
int androidCreateThreadEtc(android_thread_func_t entryFunction,
void *userData,
const char* threadName,
int32_t threadPriority,
size_t threadStackSize,
android_thread_id_t *threadId)
{
return gCreateThreadFn(entryFunction, userData, threadName,
threadPriority, threadStackSize, threadId);
}
typedef int (*android_create_thread_fn)(android_thread_func_t entryFunction,
void *userData,
const char* threadName,
int32_t threadPriority,
size_t threadStackSize,
android_thread_id_t *threadId);
// gCreateThreadFn 为静态成员变量,是一个函数 android_create_thread_fn 指针
// 默认为 androidCreateRawThreadEtc
static android_create_thread_fn gCreateThreadFn = androidCreateRawThreadEtc;
// 但是 提供了一个改变 gCreateThreadFn 函数
void androidSetCreateThreadFunc(android_create_thread_fn func)
{
gCreateThreadFn = func;
}
android::Thread 默认是能够调用 java 方法的,但是调用 java 需要 android java 虚拟机 。android java 虚拟机是 Zygote 进程启动的 ,所有的 app 进程都是 Zygote fork 的 ,所有才能够运行 java 代码 。
下面是 Zygote 进程启动时启动时,执行的一段代码
cpp
void AndroidRuntime::start(const char* className, const Vector<String8>& options, bool zygote)
{
/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
// 启动 java 虚拟机
if (startVm(&mJavaVM, &env, zygote, primary_zygote) != 0) {
return;
}
onVmCreated(env);
// 调用 startReg 函数
if (startReg(env) < 0) {
ALOGE("Unable to register all android natives\n");
return;
}
}
// startReg 函数里面修改了 gCreateThreadFn 静态全局变量
/*static*/ int AndroidRuntime::startReg(JNIEnv* env)
{
androidSetCreateThreadFunc((android_create_thread_fn) javaCreateThreadEtc);
return 0;
}
// gCreateThreadFn 变为 javaCreateThreadEtc 函数
/*static*/ int AndroidRuntime::javaCreateThreadEtc(
android_thread_func_t entryFunction,
void* userData,
const char* threadName,
int32_t threadPriority,
size_t threadStackSize,
android_thread_id_t* threadId)
{
// 创建 3 个 void* 指针 ,分别存储线程入口函数,函数参数,线程名字
void** args = (void**) malloc(3 * sizeof(void*)); // javaThreadShell must free
int result;
LOG_ALWAYS_FATAL_IF(threadName == nullptr, "threadName not provided to javaCreateThreadEtc");
args[0] = (void*) entryFunction;
args[1] = userData;
// threadName 可能是局部变量的字符串,需要 strdup 复制到堆内存,避免访问失效数据
args[2] = (void*) strdup(threadName); // javaThreadShell must free
// javaThreadShell 方法包装了 entryFunction 真正的函数入口
result = androidCreateRawThreadEtc(AndroidRuntime::javaThreadShell, args,
threadName, threadPriority, threadStackSize, threadId);
return result;
}
/*static*/ int AndroidRuntime::javaThreadShell(void* args) {
void* start = ((void**)args)[0];
void* userData = ((void **)args)[1];
char* name = (char*) ((void **)args)[2]; // we own this storage
free(args);
JNIEnv* env;
int result;
/* 让 Native 线程附加到 Java 虚拟机(JVM) */
if (javaAttachThread(name, &env) != JNI_OK)
return -1;
/*调用真正的线程入口函数*/
result = (*(android_thread_func_t)start)(userData);
// 线程方法退出后,让 Native 线程附剥离 JVM ,避免不必要的 JVM 资源占用。
javaDetachThread();
free(name);
return result;
}
static int javaAttachThread(const char* threadName, JNIEnv** pEnv)
{
JavaVMAttachArgs args;
JavaVM* vm;
jint result;
// 获取 Zygote 进程全局的 java 虚拟机对象
vm = AndroidRuntime::getJavaVM();
assert(vm != NULL);
args.version = JNI_VERSION_1_4;
args.name = (char*) threadName;
args.group = NULL;
// 让 Native 线程附加到 Java 虚拟机(JVM),从而可以使用 JNI 调用 Java 方法。
result = vm->AttachCurrentThread(pEnv, (void*) &args);
if (result != JNI_OK)
ALOGI("NOTE: attach of thread '%s' failed\n", threadName);
return result;
}
所有一个由 Zygote 进程孵化的进程,在 native 代码如果使用 android::Thread 可以调用 java 方法的
cpp
// entryFunction : 为 AndroidRuntime::javaThreadShell 启动后会调用 _threadLoop
// userData : 线程函数的的参数 ,传递的是 android::Thread this 指针
// name : 为线程名字 ,默认为 android:unnamed_thread
// threadPriority : 线程优先级
// threadStackSize : 线程栈空间大小,默认为 0
// threadId : 线程 id ,默认为 nullptr 传递的是 android::Thread 成员变量 mThread
int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
void *userData,
const char* threadName __android_unused,
int32_t threadPriority,
size_t threadStackSize,
android_thread_id_t *threadId)
{
pthread_attr_t attr;
// 初始化线程属性
pthread_attr_init(&attr);
//让新创建的线程以分离(detached)状态运行,即它会 自动释放资源,而不需要 pthread_join 来回收
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
// threadName 不为 NULL
if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {
// 创建 thread_data_t 结构体
thread_data_t* t = new thread_data_t;
// 各个成员变量赋值
t->priority = threadPriority;
t->threadName = threadName ? strdup(threadName) : NULL;
t->entryFunction = entryFunction;
t->userData = userData;
// entryFunction 赋值为 trampoline 函数
entryFunction = (android_thread_func_t)&thread_data_t::trampoline;
// userData 赋值为 t
userData = t;
}
// 若 threadStackSize 不为 0 ,就设置栈空间
if (threadStackSize) {
pthread_attr_setstacksize(&attr, threadStackSize);
}
errno = 0;
pthread_t thread;
// 创建 libutil_thread_data 结构体
libutil_thread_data* pthread_arg = new libutil_thread_data;
pthread_arg->entry_func = entryFunction;
pthread_arg->entry_func_arg = userData;
// 创建线程
int result = pthread_create(&thread, &attr,
libutil_thread_trampoline, pthread_arg);
// 释放 attr
pthread_attr_destroy(&attr);
if (result != 0) {
ALOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, %s)\n"
"(android threadPriority=%d)",
entryFunction, result, strerror(errno), threadPriority);
return 0;
}
if (threadId != nullptr) {
*threadId = (android_thread_id_t)thread; // XXX: this is not portable
}
return 1;
}
// pthread_create 入口函数 函数
// arg 为 libutil_thread_data 结构体
static void* _Nonnull libutil_thread_trampoline(void* _Nonnull arg) {
libutil_thread_data *data_ptr = static_cast<libutil_thread_data*>(arg);
// 调用 thread_data_t::trampoline 函数 参数为 thread_data_t 结构体
int result = data_ptr->entry_func(data_ptr->entry_func_arg);
// 删除 libutil_thread_data 结构体对象
delete data_ptr;
return reinterpret_cast<void*>(static_cast<uintptr_t>(result));
}
// 包装线程启动函数,在线程启动前会先运行 trampoline 函数 再执行真正的线程代码
// 为啥要包装一下呢,这是为了给线程设置线程名,
// 因为设置线程名是通过 prctl(PR_SET_NAME) 函数设置 ,该函数只有在运行的线程才有效
// 还有设置线程优先级,父线程也不知道子线程什么时候运行,设置时需要子线程ID,
// 当有子线程ID时,子线程启动函数说不定已经运行了,所以在运行子线程函数之前先包装一下,
// 设置好优先级和线程名字后在运行真正的启动函数
static int trampoline(const thread_data_t* t) {
// 取出 thread_data_t 结构体的值
thread_func_t f = t->entryFunction;
void* u = t->userData;
int prio = t->priority;
char * name = t->threadName;
// 回收 thread_data_t 结构体
delete t;
// 设置线程优先级
setpriority(PRIO_PROCESS, 0, prio);
// 如果 name 不为 空
if (name) {
// 设置线程名字
androidSetThreadName(name);
// 回收 name 字符串
free(name);
}
// 调用真正的入口函数
return f(u);
}
// 真正的入口函数
int Thread::_threadLoop(void* user)
{
// 传递的 user 为 android::Thread 对象
Thread* const self = static_cast<Thread*>(user);
// 强引用 确保 Thread 在 _threadLoop() 运行时不会被外部意外销毁
sp<Thread> strong(self->mHoldSelf);
// 弱引用
wp<Thread> weak(strong);
// 清除 mHoldSelf 对自身的引用,
self->mHoldSelf.clear();
// 获取线程 tid
self->mTid = gettid();
bool first = true;
// do while 循环
do {
bool result;
if (first) {
// 第一次执行
first = false;
// 判断是否可以开始执行 默认为 OK
self->mStatus = self->readyToRun();
result = (self->mStatus == OK);
// 如果准备好执行了,并且没有调用退出
if (result && !self->exitPending()) {
// 调用 android::Thread 虚函数 threadLoop()
result = self->threadLoop();
}
} else {
result = self->threadLoop();
}
// establish a scope for mLock
{
Mutex::Autolock _l(self->mLock);
// 如果没有准备好 ,或者 threadLoop 函数返回 false ,或者要求退出
if (result == false || self->mExitPending) {
self->mExitPending = true;
self->mRunning = false;
self->mThread = thread_id_t(-1);
// 通知等待退出的线程,已经退出了
self->mThreadExitedCondition.broadcast();
// 跳出循环 ,线程退出
break;
}
}
// 清除强引用,让线程有机会退出
strong.clear();
// 尝试将弱引用提升为强引用,如果对象还未被销毁,就返回一个有效的 sp<T>,否则返回 nullptr。
// 如果外部还有 android::Thread 对象的强引用,线程不会退出
strong = weak.promote();
} while(strong != nullptr); // android::Thread 对象强引用没有清除 ,一直循环
return 0;
}