Android Native Thread类分析

在分析Android Nativie 层的代码时,会看到很多相关Thread(线程)的函数,这里分析一下Thread的实现。

Liunx pthread 介绍

在Liunx 中,使用 pthread_create 来创建线程,函数原型如下

java 复制代码
//线程创建成功就返回 0
//线程创建成功,调用start_routine 函数,arg为传入函数的参数
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

线程退出

c 复制代码
void pthread_exit(void *retval);

比较两个线程的ID是否一致

c 复制代码
int pthread_equal(pthread_t t1, pthread_t t2); //返回0表示不相同

join

c 复制代码
int pthread_join(pthread_t thread, void **retval); //调用方线程等待thread执行完成

Liunx pthread示例

c 复制代码
#include<stdio.h>
#include <pthread.h>
#include <utils/Log.h>
#include <stdlib.h>
/* int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
                          void *(*start_routine) (void *), void *arg);*/

void *my_thread_func(void *arg){
    int i = 0;
    while(i < 10){
        printf("my thread say i:%d\n",i);
        ALOGD("my thread say i:%d\n",i);
        i++;
    }
    printf("my thread exit!!\n");
    return NULL;
}
int main(){
    //创建线程
    pthread_t my_pthread_t;
    /*返回0表示创建成功*/
    int status = pthread_create(&my_pthread_t,NULL,my_thread_func,NULL);
    if(status){
        printf("my thread create error!!");
        abort();
    }
    //while(1);
    status = pthread_join(my_pthread_t,NULL);//主线程在这里等待子线程执行完毕
    if(status){
        printf("my thread join error!!");
        abort();
    }
    printf("main thread exit!!");

    return 0;
}

Android Native Thread

Android Native Thread也是基于Liunx pthread 的一层封装,源码路径

c 复制代码
system\core\libutils\Threads.cpp
system\core\libutils\include\utils\Thread.h

先来看一下Thread.h 头文件的定义

c 复制代码
namespace android {
// ---------------------------------------------------------------------------

// DO NOT USE: please use std::thread

class Thread : virtual public RefBase
{
public:
    // Create a Thread object, but doesn't create or start the associated
    // thread. See the run() method.
    explicit            Thread(bool canCallJava = true);
    virtual             ~Thread();

    // Start the thread in threadLoop() which needs to be implemented.
    // NOLINTNEXTLINE(google-default-arguments)
    virtual status_t    run(    const char* name,
                                int32_t priority = PRIORITY_DEFAULT,
                                size_t stack = 0);
    // Ask this object's thread to exit. This function is asynchronous, when the
    // function returns the thread might still be running. Of course, this
    // function can be called from a different thread.
    virtual void        requestExit();

    // Good place to do one-time initializations
    virtual status_t    readyToRun();
    
    // Call requestExit() and wait until this object's thread exits.
    // BE VERY CAREFUL of deadlocks. In particular, it would be silly to call
    // this function from this object's thread. Will return WOULD_BLOCK in
    // that case.
            status_t    requestExitAndWait();

    // Wait until this object's thread exits. Returns immediately if not yet running.
    // Do not call from this object's thread; will return WOULD_BLOCK in that case.
            status_t    join(); //阻塞等待函数
     // Indicates whether this thread is running or not.
            bool        isRunning() const; //判断线程是否正在运行

	#if defined(__ANDROID__)
    	// Return the thread's kernel ID, same as the thread itself calling gettid(),
    	// or -1 if the thread is not running.
            	pid_t       getTid() const;
	#endif

	protected:
    	// exitPending() returns true if requestExit() has been called.
            bool        exitPending() const;
    
	private:
    	// Derived class must implement threadLoop(). The thread starts its life
    	// here. There are two ways of using the Thread object:
    	// 1) loop: if threadLoop() returns true, it will be called again if
    	//          requestExit() wasn't called.
    	// 2) once: if threadLoop() returns false, the thread will exit upon return.
    	virtual bool        threadLoop() = 0;

	//......

可以看出Thread类继承RefBase,所以Thread或者其子类都可以使用智能指针,来看一下Threads.cpp的内部实现。在Nativie层,创建一个Thread实例后,要让Thread运行起来,调用run函数

c 复制代码
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);
	//判断是否已经运行
    if (mRunning) {
        // thread already started
        return INVALID_OPERATION;
    }
    // reset status and exitPending to their default value, so we can
    // try again after an error happened (either below, or in readyToRun())
    mStatus = OK;
    mExitPending = false;
    mThread = thread_id_t(-1);

    // hold a strong reference on ourself
    mHoldSelf = this;

    mRunning = true;
    bool res;
    if (mCanCallJava) {//一般为flase
        res = createThreadEtc(_threadLoop,
                this, name, priority, stack, &mThread);
    } else {
        res = androidCreateRawThreadEtc(_threadLoop,
                this, name, priority, stack, &mThread);
    }
    if (res == false) {
        mStatus = UNKNOWN_ERROR;   // something happened!
        mRunning = false;
        mThread = thread_id_t(-1);
        mHoldSelf.clear();  // "this" may have gone away after this.

        return UNKNOWN_ERROR;
    }

    // Do not refer to mStatus here: The thread is already running (may, in fact
    // already have exited with a valid mStatus result). The OK indication
    // here merely indicates successfully starting the thread and does not
    // imply successful termination/execution.
    return OK;
}

先判断该线程是否已经运行,如果已经运行的话,直接返回。然后调用androidCreateRawThreadEtc函数

c 复制代码
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_t thread;
    int result = pthread_create(&thread, &attr,
                    (android_pthread_entry)entryFunction, userData);
    pthread_attr_destroy(&attr);
    //......

这里可以看到,Android Native层创建线程也是基于Liunx的pthread_create实现的。调用pthread_create后,开始执行entryFunction函数。entryFunction函数传进来的,是androidCreateRawThreadEtc的第一个参数,即_threadLoop

c 复制代码
int Thread::_threadLoop(void* user)
{
	//......
	bool first = true;

    do {
        bool result;
        if (first) {
            first = false;
            self->mStatus = self->readyToRun();
            result = (self->mStatus == OK);

            if (result && !self->exitPending()) {
                result = self->threadLoop();
            }
        } else {
            result = self->threadLoop();
        }
        // establish a scope for mLock
        {
        Mutex::Autolock _l(self->mLock);
        if (result == false || self->mExitPending) {
            self->mExitPending = true;
            self->mRunning = false;
            // clear thread ID so that requestExitAndWait() does not exit if
            // called by a new thread using the same thread ID as this one.
            self->mThread = thread_id_t(-1);
            // note that interested observers blocked in requestExitAndWait are
            // awoken by broadcast, but blocked on mLock until break exits scope
            self->mThreadExitedCondition.broadcast();
            break;
        }
        }

        // Release our strong reference, to let a chance to the thread
        // to die a peaceful death.
        strong.clear();
        // And immediately, re-acquire a strong reference for the next loop
        strong = weak.promote();
    } while(strong != nullptr);

    return 0;
}

_threadLoop 函数体是一个循环,循环体执行的第一次,会调用readyToRun函数,第一次调用时readyToRun返回ture且exitPending为false,会调用threadLoop函数。不是第一次执行循环体的话,会直接调用threadLoop函数。

threadLoop返回false或者mExitPending为true会结束循环,线程结束。

其中mExitPending在调用requestExit 时设置为true

c 复制代码
void Thread::requestExit()
{
    Mutex::Autolock _l(mLock);
    mExitPending = true;
}

Android Native Thread 示例

c 复制代码
//MyThread.h
#ifndef ANDROID_MYTHREAD_H
#define ANDROID_MYTHREAD_H
#include <utils/Thread.h>
namespace android{
    class MyThread : public Thread
    {
    public:
        MyThread();
        virtual ~MyThread();

    private:
        virtual void        onFirstRef();
        virtual status_t    readyToRun();
        virtual bool        threadLoop();
        int count = 0;
    };
};
#endif

//MyThread.cpp
#include<stdio.h>
#include "MyThread.h"
namespace android {

    MyThread::MyThread() : Thread(false){
        printf("new MyThread!!\n");
    }

    MyThread::~MyThread() {
        printf("desory MyThread!!\n");
    }

    void MyThread::onFirstRef() {
        printf("MyThread onFirstRef!!\n");
    }

    status_t MyThread::readyToRun() {
        printf("MyThread readyToRun!!\n");
        return NO_ERROR;
    }

    bool MyThread::threadLoop() {
        printf("MyThread threadLoop count:%d!!\n",count);
        count++;
        if(count == 10)
            return false;
        return true;
    }
}

//main.cpp
#include<stdio.h>
#include "MyThread.h"
using namespace android;
int main() {
    sp <MyThread> mythread = new MyThread();
    mythread->run("Mythread",PRIORITY_DEFAULT);
//    while(1){
//        if(!mythread->isRunning()){
//            break;
//        }
//    }
    mythread->join();
    printf("main thread is exit!!\n");
    return 0;
}
;

总结

  • Android Native Thread 是基于Liunx 的 pthread 的一层封装
  • Thread 继承RefBase,可以使用智能指针,调用其onFirstRef函数
  • new 一个 Thread 并调用其run函数,可以新建一个线程
  • 创建一个线程后,先调用readyToRun,再调用threadLoop函数
  • threadLoop返回false或者调用过requestExit,线程退出
相关推荐
莞凰14 小时前
昇腾CANN的“灵脉根基“:Runtime仓库探秘
android·人工智能·transformer
NiceCloud喜云15 小时前
Claude Files API 深入:从上传、复用到配额管理的工程化指南
android·java·数据库·人工智能·python·json·飞书
ujainu15 小时前
CANN pto-isa:虚拟指令集如何连接编译与执行
android·ascend
赏金术士16 小时前
第六章:UI组件与Material3主题
android·ui·kotlin·compose
TechMerger17 小时前
Android 17 重磅重构!服役 20 年的 MessageQueue 迎来无锁改造,卡顿大幅优化!
android·性能优化
yuhuofei202120 小时前
【Python入门】Python中字符串相关拓展
android·java·python
dalancon20 小时前
Android Input Spy Window
android
dalancon1 天前
InputDispatcher派发事件,查找目标窗口
android
我命由我123451 天前
Android Framework P3 - MediaServer 进程、认识 ServiceManager 进程
android·c语言·开发语言·c++·visualstudio·visual studio·android runtime
天才少年曾牛1 天前
Android14 新增系统服务后,应用调用出现 “hidden api” 警告的原因与解决方案
android·frameworks