Android Framework层线程设计

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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值