Android Framework层线程设计

来源:互联网 发布:走路赚钱的软件 编辑:程序博客网 时间:2024/06/05 03:08

framework层的thread是c++实现的,定义在utils/threads.h,实现在Threads.cpp (system\core\libutils)。
</pre><pre name="code" class="cpp">首先看看定义:

</pre><pre name="code" class="cpp">class Thread : virtual public RefBase{public:    // Create aThread object, but doesn't create or start the associated    // thread.See the run() method.                        Thread(bool canCallJava= true);   virtual             ~Thread();     // Startthe thread in threadLoop() which needs to be implemented.    virtualstatus_t    run(    const char* name = 0,                                int32_tpriority = PRIORITY_DEFAULT,                                size_t stack =0);       // Ask thisobject's thread to exit. This function is asynchronous, when the    // functionreturns the thread might still be running. Of course, this    // functioncan be called from a different thread.    virtualvoid        requestExit();     // Goodplace to do one-time initializations    virtualstatus_t    readyToRun();       // CallrequestExit() and wait until this object's thread exits.    // BE VERYCAREFUL of deadlocks. In particular, it would be silly to call    // thisfunction from this object's thread. Will return WOULD_BLOCK in    // thatcase.           status_t    requestExitAndWait();     // Waituntil this object's thread exits. Returns immediately if not yet running.    // Do notcall 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; #ifdef HAVE_ANDROID_OS    // Returnthe thread's kernel ID, same as the thread itself calling gettid() or    //androidGetTid(), 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:    // Derivedclass 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.    virtualbool        threadLoop() = 0; private:    Thread&operator=(const Thread&);    static  int             _threadLoop(void* user);    const   bool           mCanCallJava;    // alwayshold mLock when reading or writing           thread_id_t     mThread;    mutableMutex           mLock;           Condition      mThreadExitedCondition;           status_t        mStatus;    // notethat all accesses of mExitPending and mRunning need to hold mLock    volatilebool           mExitPending;    volatilebool           mRunning;           sp<Thread>      mHoldSelf;#ifdef HAVE_ANDROID_OS    // legacyfor debugging, not used by getTid() as it is set by the child thread    // and sois not initialized until the child reaches that point           pid_t           mTid;#endif};

thread继承类RefBase,所以在onFirstRef中,调用了run函数

void AudioFlinger::PlaybackThread::onFirstRef(){    run(mName,ANDROID_PRIORITY_URGENT_AUDIO);}status_t Thread::run(const char* name, int32_tpriority, size_t stack){ ...    if(mCanCallJava) {        res =createThreadEtc(_threadLoop,               this, name, priority, stack, &mThread);    } else {        res =androidCreateRawThreadEtc(_threadLoop,               this, name, priority, stack, &mThread);    } ...   }int Thread::_threadLoop(void* user){...    do {...        result= self->threadLoop();...        if(result == false || self->mExitPending) {        self->mThreadExitedCondition.broadcast();           break;        }    }while(strong != 0);    return 0;}


threadLoop是个虚函数,继承Thread的类需要自己去实现这个函数,实现方式为

void AudioFlinger::AsyncCallbackThread::onFirstRef(){   run("Offload Cbk", ANDROID_PRIORITY_URGENT_AUDIO);} bool AudioFlinger::AsyncCallbackThread::threadLoop(){    while(!exitPending()) {       ...    }    returnfalse;}


这里exitPending是这么定义的

bool Thread::exitPending() const{    returnmExitPending;}


所以,你可以选择在threadLoop里循环,也可以选择在_threadLoop里循环。


线程终止于run函数运行退出,要想退出一个线程,可以使用下面的接口:

1. 要求线程退出的线程不被block

void Thread::requestExit(){   mExitPending = true;}


2. 要求线程退出的线程被block,直到线程真正退出,注意self->mThreadExitedCondition.broadcast()出现在_threadLoop退出前夕

status_t Thread::requestExitAndWait(){     mExitPending = true;    while(mRunning == true) {       mThreadExitedCondition.wait(mLock);    }   mExitPending = false;     returnmStatus;}


看看具体的例子,AudioFlinger中threadBase里的exit:

void AudioFlinger::ThreadBase::exit(){        AutoMutex lock(mLock);        requestExit();       mWaitWorkCV.broadcast();   requestExitAndWait();}


在AudioFlinger析构的时候

AudioFlinger::~AudioFlinger(){...    while(!mPlaybackThreads.isEmpty()) {        closeOutput_nonvirtual(mPlaybackThreads.keyAt(0));    }...}


函数closeOutput_nonvirtual内部调了thread->exit();


下面看看join:

status_t Thread::join(){   Mutex::Autolock _l(mLock);    if (mThread== getThreadId()) {        returnWOULD_BLOCK;    }    while(mRunning == true) {       mThreadExitedCondition.wait(mLock);    }    returnmStatus;}


所以join是block调用join的线程,直到mThreadExitedCondition broadcast,也就是说,直到mThreadExitedCondition所属的线程退出。

比如T.join()意味着执行这句程序的线程被block,直到线程T推出

带时间参数的join表示最多只等待一段时间,过期不候。


0 0
原创粉丝点击