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,线程退出
相关推荐
Python私教30 分钟前
Python ORM 框架 SQLModel 快速入门教程
android·java·python
编程乐学2 小时前
基于Android Studio 蜜雪冰城(奶茶饮品点餐)—原创
android·gitee·android studio·大作业·安卓课设·奶茶点餐
problc3 小时前
Android中的引用类型:Weak Reference, Soft Reference, Phantom Reference 和 WeakHashMap
android
IH_LZH3 小时前
Broadcast:Android中实现组件及进程间通信
android·java·android studio·broadcast
去看全世界的云3 小时前
【Android】Handler用法及原理解析
android·java
机器之心3 小时前
o1 带火的 CoT 到底行不行?新论文引发了论战
android·人工智能
机器之心3 小时前
从架构、工艺到能效表现,全面了解 LLM 硬件加速,这篇综述就够了
android·人工智能
AntDreamer4 小时前
在实际开发中,如何根据项目需求调整 RecyclerView 的缓存策略?
android·java·缓存·面试·性能优化·kotlin
运维Z叔5 小时前
云安全 | AWS S3存储桶安全设计缺陷分析
android·网络·网络协议·tcp/ip·安全·云计算·aws
Reese_Cool7 小时前
【C语言二级考试】循环结构设计
android·java·c语言·开发语言