Android native/C++层Thread线程实现源码分析

在Android native(C++)层若想要创建一个线程则可以使用android平台native实现的Thread类来创建【当然你也可以直接使用C++标准库实现的std::thread,需引入头文件 #include,后续有时间再分析该标准库的实现】,而该类做了跨平台线程调用接口的处理和封装,具备了跨平台运行能力。

本系列文章分析的安卓源码版本:【Android 10.0 版本】

在此主要分析Android平台上的实现部分。

在native层使用该类必须引用android命名空间,因为该类是在android命名空间实现的,并引用该头文件【system/core/libutils/include/utils/Threads.h】,即可在自己的cpp文件中如下引用:

#include <utils/threads.h>

Threads.h文件内容如下:

// [system/core/libutils/include/utils/Threads.h]

#ifndef _LIBS_UTILS_THREADS_H
#define _LIBS_UTILS_THREADS_H

/*
 * Please, DO NOT USE!
 *
 * This file is here only for legacy reasons. Instead, include directly
 * the headers you need below.
 *
 */

#include <utils/AndroidThreads.h>

// __cplusplus (C++)该宏定义的作用是:告诉C++编译器将这下面包含的头文件中的方法实现,
// 都按照C编译器的方式来处理编译,然后才能用于和C代码库相互链接。
// 可参考这篇文章很详细的介绍:【#ifdef __cplusplus 有什么作用】
// https://blog.csdn.net/thanklife/article/details/7362893
#ifdef __cplusplus
#include <utils/Condition.h>
#include <utils/Errors.h>
#include <utils/Mutex.h>
#include <utils/RWLock.h>
#include <utils/Thread.h>
#endif

#endif // _LIBS_UTILS_THREADS_H

该头文件是一个线程功能集合体,提供了好几个头文件,其实若只是需要使用Thread线程类,我们不需要引用这么多头文件,因此正如文件中英文部分所指出的:
注意此处的英文注释的意思:意思就是最好不要再使用【threads.h】这个头文件,因为它是历史遗留原因造成的,相反,我们应该直接使用include下面所需的头文件即可,因此想用哪个头文件功能就直接引用它即可。
【另外主要区别就是:该threads.h头文件其实是用C编译器的方式编译代码的,因此在C++编程时不需要这么做】

因此可以更简单的头文件引入方式,如下:
只引入需要使用Thread线程类的头文件

#include <utils/Thread.h>

Thread类图:
Thread类图
Thread类声明:
声明的功能比较简单,类声明在android命名空间。

// [system/core/libutils/include/utils/Thread.h]

#ifndef _LIBS_UTILS_THREAD_H
#define _LIBS_UTILS_THREAD_H

#include <stdint.h>
#include <sys/types.h>
#include <time.h>

#if !defined(_WIN32)
# include <pthread.h>
#endif

#include <utils/Condition.h>
#include <utils/Errors.h>
#include <utils/Mutex.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
#include <utils/ThreadDefs.h>

// ---------------------------------------------------------------------------
namespace android {
   
   
// ---------------------------------------------------------------------------

// 此处的英文表示,请不要使用该类,请使用std::thread类【C++标准库提供】来实现自己的线程,
// 应该是android自己实现的该类只提供给安卓native内部使用的吧。
// DO NOT USE: please use std::thread
// RefBase类是安卓智能指针的实现,此处不展开分析,可见后续相关分析章节
class Thread : virtual public RefBase
{
   
   
public:
    // 显示调用构造函数
    // explicit修饰符表示该类构造函数必须显示创建调用
    // Create a Thread object, but doesn't create or start the associated
    // thread. See the run() method.
    explicit            Thread(bool canCallJava = true);
    virtual             ~Thread();

    // 启动线程运行
    // 该方法可只传入线程名,其他两个参数为默认值
    // priority:该参数表示当前线程的优先级别,主要用于CPU线程调用的处理
    // 其取值范围常量定义在<utils/ThreadDefs.h>该头文件中
    // stack:该参数表示线程大小
    // 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();
    
    // 请求退出并等待退出完毕后该方法才返回(调用端),
    // 即该方法会阻塞调用端线程,直到彻底退出后才返回。
    // 警告:必须小心调用该方法,避免造成死锁,即千万别在当前线程中调用该方法,否则会返回错误状态(WOULD_BLOCK)
    // 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();

    // 等待线程(阻塞运行完毕),即该方法调用后会阻塞调用端线程,等待该线程执行完毕退出才返回调用端。
    // 阻塞当前的(调用)线程,直到另外一个线程运行结束。
    // 注意:若该线程未启动,则会立即返回。
    // 警告:不要在该线程中调用该方法,否则会返回错误状态(WOULD_BLOCK)
    // 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__)
	// 若存在安卓平台宏定义,则进入此处
	
	// 返回该线程ID(线程内核ID)
	// 注意:若该线程未启动则返回-1
    // 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:
	// 线程循环执行开始(方法)
    // 重点:该方法就是子类需要实现的该线程中执行任务的方法,另外该线程的返回值有不同作用:
    // 1)循环执行:若该方法返回true且未调用过requestExit()方法,则该方法将再次被调用执行即形成循环调用。
    // 2)执行一次:若放回false,则该线程在该方法返回时将会退出。
    // 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;

private:
	// 将赋值运算符= 函数放在此处声明的含义就是,不允许Thread线程类对象之间进行赋值
    Thread& operator=(const Thread&);
    // 线程循环方法(主要是用于线程启动时传入的方法引用【指针】)
    static  int             _threadLoop(void* user);
    // 是否可以调用Java
    const   bool            mCanCallJava;
    // 线程ID信息,读写都需要加锁
    // always hold mLock when reading or writing
            thread_id_t     mThread;
    // 互斥锁【主要此处使用了mutable关键字来修饰该变量】
    // 备注:被mutable修饰的变量,可以突破const的限制,在被const修饰的函数里面也能被修改。 
    mutable Mutex           mLock;
    // 线程退出条件变量
            Condition       mThreadExitedCondition;
    // 线程状态
            status_t        mStatus;
    // 是否该线程已请求退出(正在退出或已退出完成状态)
    // 备注:
    // volatile关键字可以用来提醒编译器它后面所定义的变量随时有可能改变,
    // 因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。
    // 如果没有volatile关键字,则编译器可能优化读取和存储,可能暂
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值