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,线程退出
相关推荐
踏雪羽翼3 小时前
android TextView实现文字字符不同方向显示
android·自定义view·textview方向·文字方向·textview文字显示方向·文字旋转·textview文字旋转
lxysbly3 小时前
安卓玩MRP冒泡游戏:模拟器下载与使用方法
android·游戏
夏沫琅琊5 小时前
Android 各类日志全面解析(含特点、分析方法、实战案例)
android
程序员JerrySUN6 小时前
OP-TEE + YOLOv8:从“加密权重”到“内存中解密并推理”的完整实战记录
android·java·开发语言·redis·yolo·架构
TeleostNaCl7 小时前
Android | 启用 TextView 跑马灯效果的方法
android·经验分享·android runtime
TheNextByte18 小时前
Android USB文件传输无法使用?5种解决方法
android
quanyechacsdn9 小时前
Android Studio创建库文件用jitpack构建后使用implementation方式引用
android·ide·kotlin·android studio·implementation·android 库文件·使用jitpack
程序员陆业聪10 小时前
聊聊2026年Android开发会是什么样
android
编程大师哥10 小时前
Android分层
android
极客小云12 小时前
【深入理解 Android 中的 build.gradle 文件】
android·安卓·安全架构·安全性测试