Android native层多线程类Thread

71 阅读3分钟

1.Linux中c语言创建线程方法--posix

首先看下用于创建线程的pthread_create的方法参数

int pthread_create(pthread_t *tidp,   
                    const pthread_attr_t *attr, 
                    void *(*start_rtn)(void*), 
                    void *arg);
                    
//第一个是pthread_t结构体,表示创建的线程信息,传递给pthread_create方法后可以获取对应线程信息

// ‌**attr**‌:这是一个指向[pthread_attr_t**]类型的指针,用于设置线程的各种属性。
//在实际使用中,通常将其设置为NULL,以使用默认属性‌12。//**start_rtn**‌:这是一个函数指针,指向新创建线程将要执行的函数。
//这个函数必须接受一个void*类型的参数,并且返回void*类型的结果。
//如果不需要传递参数给线程函数,可以将arg设置为NULL‌

// **arg**‌:这是一个void*类型的参数,用于传递给start_rtn函数的参数。
//如果不需要传递参数,可以将arg设置为NULL。
//如果需要传递多个参数,可以通过结构体等方式传递‌

简单写一个c方法创建线程;线程中会执行thread_posix_function方法,并打印log

#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <utils/Log.h>
 void *thread_posix_function(void *arg) {
  (void*)arg;
  int i;
  for ( i=0; i<30; i++) {
    printf("hello thread i = %d\n",i);
    ALOGD("hello thread i = %d\n",i);
    sleep(1);
  }
  return NULL;
}
int main(void) {
  pthread_t mythread;
  
  if ( pthread_create( &mythread, NULL, thread_posix_function, NULL) ) {
    ALOGD("error creating thread.");
    abort();
  }
  if ( pthread_join ( mythread, NULL ) ) {
    ALOGD("error joining thread.");
    abort();
  }
  ALOGD("hello thread has run end exit\n");
  exit(0);
}

2.Android native中用到Thread

用到的继承Thread的一些类

// \frameworks\base\cmds\bootanimation\BootAnimation.h
BootAnimation继承Thread
class BootAnimation : public Thread, public IBinder::DeathRecipient
{

// \frameworks\native\services\surfaceflinger\StartPropertySetThread.h
开机启动线程
class StartPropertySetThread : public Thread {

等等......

首先,启动线程都会调用run方法,我看看下Thread的run方法

status_t Thread::run(const char* name, int32_t priority, size_t stack)
{

    Mutex::Autolock _l(mLock);

    bool res;
    //这里run其实就是创建现了线程
    if (mCanCallJava) {
        res = createThreadEtc(_threadLoop,
                this, name, priority, stack, &mThread);
    } else {
        res = androidCreateRawThreadEtc(_threadLoop,
                this, name, priority, stack, &mThread);
    }
}

//继续看androidCreateRawThreadEtc 方法,这里有通过pthread_create创建线程

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)
{


    errno = 0;
    pthread_t thread;
    //entryFunction这个就是线程中执行的方法,也就是run方法里面的_threadLoop
    int result = pthread_create(&thread, &attr,
                    (android_pthread_entry)entryFunction, userData);
    pthread_attr_destroy(&attr);
    if (result != 0) {
        ALOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, %s)\n"
             "(android threadPriority=%d)",
            entryFunction, result, strerror(errno), threadPriority);
        return 0;
    }

    // Note that *threadID is directly available to the parent only, as it is
    // assigned after the child starts.  Use memory barrier / lock if the child
    // or other threads also need access.
    if (threadId != NULL) {
        *threadId = (android_thread_id_t)thread; // XXX: this is not portable
    }
    return 1;
}


看到这里也就明白了:创建线程,然后线程中会执行Threads.cpp的_threadLoop方法

接着看下_threadLoop方法

int Thread::_threadLoop(void* user)
{


    bool first = true;

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

            if (result && !self->exitPending()) {
                result = self->threadLoop();
            }
        } else {
            result = self->threadLoop();
        }
        Mutex::Autolock _l(self->mLock);
        if (result == false || self->mExitPending) {
            self->mExitPending = true;
            self->mRunning = false;

            self->mThread = thread_id_t(-1);

            self->mThreadExitedCondition.broadcast();
            break;
        }
        strong.clear();
        // And immediately, re-acquire a strong reference for the next loop
        strong = weak.promote();
    } while(strong != 0);

    return 0;
}

总结:

  • 创建线程后,先执行self->readyToRun();再执行self->threadLoop()

  • 会一直循环执行do{}while中的逻辑。如果self->threadLoop();返回false就会break,退出循环,线程执行结束;如果self->threadLoop();一直返回true,则一直循环