Android Binder處理序間通訊---註冊Service組件---啟動Binder線程池

來源:互聯網
上載者:User

標籤:android   style   blog   class   c   code   

本文參考《Android系統原始碼情景分析》,作者羅昇陽

一、測試代碼:

       ~/Android/external/binder/server

        ----FregServer.cpp

        ~/Android/external/binder/common

        ----IFregService.cpp

        ----IFregService.h

       ~/Android/external/binder/client

       ----FregClient.cpp


       Binder庫(libbinder)代碼:

       ~/Android/frameworks/base/libs/binder

       ----BpBinder.cpp

       ----Parcel.cpp

       ----ProcessState.cpp

       ----Binder.cpp

       ----IInterface.cpp

       ----IPCThreadState.cpp

       ----IServiceManager.cpp

       ----Static.cpp

       ~/Android/frameworks/base/include/binder

       ----Binder.h

       ----BpBinder.h

       ----IInterface.h

       ----IPCThreadState.h

       ----IServiceManager.h

       ----IBinder.h

       ----Parcel.h

       ----ProcessState.h


        驅動層代碼:

       ~/Android//kernel/goldfish/drivers/staging/android

       ----binder.c

       ----binder.h


二、源碼分析

      繼續上一篇Android Binder處理序間通訊---註冊Service組件---發送和處理BC_REPLY返回協議http://blog.csdn.net/jltxgcy/article/details/26339313,執行完waitForResponse函數,參考Android Binder處理序間通訊---註冊Service組件---Client發送BC_TRANSACTION。應該返回IPCThreadState類的transact方法,再返回BpBinder類的transact函數,最後返回BpServiceManager類addService函數。最後再返回FregService類的main函數,實現如下:

       ~/Android/external/binder/server

        ----FregServer.cpp

int main(int argc, char** argv){FregService::instantiate();ProcessState::self()->startThreadPool();//啟動一個Binder線程池IPCThreadState::self()->joinThreadPool();//主線程加入線程池return 0;}
      首先當前進程的ProcessState對象的成員函數startThreadPool來啟動一個Binder線程池,接著繼續調用當前線程的IPCThreadState對象的成員函數joinThreadPool,將當前線程加入到前面所啟動的Binder線程池中去等待和處理來自Client進程的處理序間通訊請求。

      下面我們就分析ProcessState類的成員函數startThreadPool的實現,在分析過程中,同時也會分析IPCThreadState類的成員函數joinThreadPool的實現。

       ProcessState類的成員函數startThreadPool的實現如下:

       ~/Android/frameworks/base/libs/binder

       ----ProcessState.cpp

void ProcessState::startThreadPool(){    AutoMutex _l(mLock);    if (!mThreadPoolStarted) {//預設值為false        mThreadPoolStarted = true;//防止它的成員函數spawnPooledThread被重複調用來啟動Binder線程池        spawnPooledThread(true);    }}
     當前進程的ProcessState對象的成員變數mThreadPoolStarted被初始化為false,當它將一個Binder線程池啟動起來之後,就會將內部的成員變數mThreadPoolStarted的值設定為true,防止它的成員函數spawnPooledThread被重複調用來啟動Binder線程池。spawnPooledThread函數實現如下:

       ~/Android/frameworks/base/libs/binder

       ----ProcessState.cpp

void ProcessState::spawnPooledThread(bool isMain){    if (mThreadPoolStarted) {        int32_t s = android_atomic_add(1, &mThreadPoolSeq);        char buf[32];        sprintf(buf, "Binder Thread #%d", s);        LOGV("Spawning new pooled thread, name=%s\n", buf);        sp<Thread> t = new PoolThread(isMain);//isMain為true        t->run(buf);//啟動一個新的線程    }}
       建立了一個PoolThread對象t,調用它的成員函數run來啟動一個新的線程。

       PoolThread類繼承了線程類Thread,並且重寫了它的線程入口成員函數threadLoop,因此當一個PoolThread對象t所對應的線程啟動起來之後,它的成員函數threadLoop就會被調用。實現如下:

       ~/Android/frameworks/base/libs/binder

       ----ProcessState.cpp

class PoolThread : public Thread{public:    PoolThread(bool isMain)        : mIsMain(isMain)//isMain為true    {    }    protected:    virtual bool threadLoop()    {        IPCThreadState::self()->joinThreadPool(mIsMain);//isMain為true        return false;    }        const bool mIsMain;};
      和主線程一樣調用了IPCThreadState類的成員函數joinThreadPool。實現如下:

       ~/Android/frameworks/base/libs/binder

       ----IPCThreadState.cpp

void IPCThreadState::joinThreadPool(bool isMain)//預設值為true{    .........    mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER);//isMain為true,BC_ENTER_LOOPER        ........            status_t result;    do {        int32_t cmd;                .......        result = talkWithDriver();//將自己註冊到Binder線程池中,一個無線迴圈中不斷等待處理序間通訊請求        if (result >= NO_ERROR) {            size_t IN = mIn.dataAvail();            if (IN < sizeof(int32_t)) continue;            cmd = mIn.readInt32();            ........            result = executeCommand(cmd);//處理處理序間通訊請求        }               .........        if(result == TIMED_OUT && !isMain) {//一直為false,因為isMain為true            break;        }    } while (result != -ECONNREFUSED && result != -EBADF);    ........        mOut.writeInt32(BC_EXIT_LOOPER);//退出Binder線程池    talkWithDriver(false);}
       參數isMain是一個預設參數,它的預設值為true。從前面的調用過程可以知道,無論是FregServer進程的主線程,還是FregServer進程剛才所建立的線程,它們都是主動(isMain為true)請求加入到Binder線程池的,即它們都不是由於Binder驅動程式請求建立而加入到Binder線程池的。

       一個Binder線程的生命週期可以劃分為三個階段:

       第一階段是將自己註冊到Binder線程池中;

       第二階段是一個無線迴圈中不斷等待和處理處理序間通訊請求;
       第三階段是退出Binder線程池。

       

       最後執行完的結果是FregServer有兩個線程,睡眠等待處理序間通訊資料的到來。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.