在分析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,线程退出