<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ??????? 在Android中ProcessState是客戶端和服務端公共的部分,作為Binder通信的基礎,ProcessState是一個singleton類,每個 進程只有一個對象,這個對象負責打開Binder驅動,建立線程池,讓其進程里面的所有線程都能通過Binder通信。 與之相關的是IPCThreadState,每個線程都有一個IPCThreadState實例登記在Linux線程的上下文附屬數據中,主要負責 Binder的讀取,寫入和請求處理框架。IPCThreadState在構造的時候獲取進程的ProcessState并記錄在自己的成員變量 mProcess中,通過mProcess可以獲得Binder的句柄。 ~~~ frameworks/base/include/binder/ProcessState.h class ProcessState : public virtual RefBase { public: static sp<ProcessState> self(); // 單例模式,獲取實例 void setContextObject(const sp<IBinder>& object); sp<IBinder> getContextObject(const sp<IBinder>& caller); void setContextObject(const sp<IBinder>& object, const String16& name); sp<IBinder> getContextObject(const String16& name, const sp<IBinder>& caller); void startThreadePool(); typdef bool (*context_check_func)(const String16& name, const sp<IBinder>& caller, void* userData); bool isContextManager(void) const; bool becomeContextManager(context_check_func checkFunc, void* userData); sp<IBinder> getStrongProxyForHandle(int32_t handle); wp<IBinder> getWeakProxyForHandle(int32_t handle); void espungeHandle(int32_t handle, IBinder* binder); void spawnPooledThread(boot isMain); private: friend class IPCThreadState; ProcessState(); ~ProcessState; ProcessState(const ProcessState& o); ProcessState& operator=(const ProcessState& o); struct hdndle_entry { IBinder* binder; RefBase::weakref_type* refs; }; handle_entry* lookupHandleLocked(int32_t handle); int mDriverFD; // 打開的binder驅動文件描述符 void* mVMStart; Vector<handle_entry> mHandleToObject; bool mManagerContexts; context_check_func mBinderContextCheckFunc; void* mBinderContextUserData; KeyedVector<String16, sp<IBinder> > mContexts; // 映射,服務名字 和 IBinder對應 bool mThreadPoolStarted; // 線程池是否已經創建 volatile int32_t mThreadPoolSeq; // 這個進程中啟動線程個數 }; ~~~ **1)獲得ProcessState的實例** ~~~ sp<ProcessState> proc(ProcessState::self()); 調用函數: sp<ProcessState> ProcessState::self() { if (gProcess != NULL) return gProcess; AutoMutext _l(gProcessMutex); if(gProcess == NULL) gProcess = new ProcessState; return gProcess; } 進入構造函數: ProcessState::ProcessState() : mDriverFD(open_driver()) , mVMStart(MAP_FAILED), , mManagerContexts(false) , mBinderContextCheckFunc(NULL) , mBinderContextUserData(NULL) , mThradPoolStarted(false) , mThreadPoolSeq(1) { } ~~~ 這個構造函數里面調用open_driver()打開了/dev/binder設備驅動文件,返回文件描述符。這樣我們就能通過這個mDriverFd 來和binder驅動交互了。 **2)創建線程ProcessState::self()->startThreadPool();** ~~~ void ProcessState::startThreadPool() { AutoMutex _l(mLock); if(!mThreadPoolStarted) { mThreadPoolStarted = true; spawnPooledThread(true); } } void ProcessState::spawnPoolThread(bool isMain) { if (mThreadPoolStarted) { int32_t s = android_atomic_add(1, &mThreadPoolSeq); sp<Thread> t = new PoolThread(isMain); t->run(buf); } } ~~~ ~~~ 其實這里就是創建一個線程PoolThread,而PoolThread是一個繼承于Thread的類。所以調用t->run()之后相當于調用 PoolThread類的threadLoop()函數,我們來看看PoolThread類的threadLoop線程函數。 virtual bool threadLoop() { IPCThreadState::self()->joinThreadPool(mIsMain); // 這里線程函數調用了一次IPCThreadState::self()->joinThreadPool()后就退出了 return false; } ~~~ **3)IPCThreadState::self()->joinThreadPool();** 我們知道:進程調用spawnPoolThread()創建了一個線程,執行joinThreadPool(),而主線程也是調用這個函數。唯一區別是參數,主線程調用的joinThreadPool(true),創建的線程調用的是jointThreadPool(false)。 下面我們來分析下這個函數,首先我們來看看IPCThreadState這個類 ~~~ frameworks/base/include/IPCThreadState.h class IPCThreadState { public: static IPCThreadState* self(); sp<ProcessState> process(); ...... void joinThradPool(bool isMain = true); status_t transact(int32_t handle, uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags); void incStrongHandle(int32_t handle); void decStrongHandle(int32_t handle); void incWeakHandle(int32_t handle); void decWeakHandle(int32_t handle); private: IPCThraedState(); ~IPCThreadState(); status_t sendReplay(const Parcel& reply, uint32_t flags); status_t waitForResponse(Parcel& reply, status_t *acquireResult = NULL); status_t talkWithDriver(bool doReceice = true); status_t writeTransactionData(); status_t executeCommand(); private: sp<ProcessState> mProcess; Vector<BBinder> mPendingStrongDerefs; Vector<RefBase::weakref_type*> mPendingWeakDerefs; Parcel mIn; Parcel mOut; } 上面是IPCThreadState類常用的幾個函數。 IPCThreadState* IPCThreadState::self() { if(gHaveTLS) { // 第一次進來肯定為false restart: const pthread_key_t k = gTLS; IPCThreadState* st = (IPCThreadState*)pthread_getspecific(k); if(st) return st; return new IPCThreadState; // new 一個IPCThreadState對象 } if(gShutdown) return NULL; pthread_mutex_lock(&gTLSMutex); if(!gHaveTLS) { // 第一個參數為指向一個鍵值的指針,第二個參數指明一個destructor函數,當線程結束時調用 if(phread_key_create(&gTLS, threadDestructor) != 0) { pthread_mutex_unlock(&gTLSMutex); return NULL; } gHaveTLS = true; } pthread_mutex_unlock(&gTLSMutex); goto restart; } ~~~ 下面來說明下線程中特有的線程存儲:Thread Specific Data. 在多線程中,所有線程共享程序中變量,如果每一個線程都希望單獨擁有它,就需要線程存儲了。即一個變量表面看起來是 全局變量,所有線程都可以使用它,它的值在每一個線程都是單獨存儲的。 **用法:** ???? ?1)創建一個類型為pthread_key_t 類型變量 ???? ?2)pthread_key_create()創建改變量,第二個參數表上一個清理函數,用來在線程釋放該線程存儲的時候調用。 ????? 3)當線程中需要存儲特殊值的時候,可以用pthread_setspecific(),第一個參數為pthread_key_t 變量,第二個參數為void* 變量,可以存儲任何類型的值。 ???? ?4)當需要取出存儲值的時候,調用pthread_getspecific(),返回void*類型變量值。 好了我們現在知道pthread_key_t是干什么用的了?既然代碼中有pthread_getspecific()獲取IPCThreadState*對象的函數那么肯定有設置這個變量值的地方?我們找到IPCThreadState的構造函數: ~~~ IPCThreadState:IPCThreadState() : mProcess(ProcessState::self()), mMyThreadId(androidGetTid()), mStrictModePolicy(0), mLastTransactionBinderFlags(0) { pthread_setspecific(gTLS, this); // 設置為當前this 指針 clearCaller(); mIn.setDataCapacity(256); // 這里mIn 和 mOut分別表示Binder輸入輸出的變量,我們后面分析 mOut.setDataCapacity(256); } ~~~ ~~~ 最后進入IPCThreadState::joinThreadPool(bool isMain) void IPCThreadState::joinThreadPool(bool isMain) // 默認為true { mOut.writeInt32(isMain ? BC_ENTER_LOOPER : BC_REGISTER_LOOPER); do { int32_t cmd; if(mIn.dataPosition() >= mIn.dataSize()){ size_t numPending = mPendingWeakDerefs.size(); if(numPending > 0) { for(size_t i = 0; i < numPending; i++) { RefBase::weakref_type* refs = mPendingWeakDerefs[i]; refs->decWeak(mProcess.get); } mPendingWeakDerefs.clear(); } numPending = mPendingStrongDerefs.size(); if(numPending > 0) { for(sizt_t i = 0; i < numPending; i++) { BBinder* obj = mPendingStrongDerefs[i]; obj->decStrong(mProcess.get); } mPendingStrongDerefs.clear(); } } // 讀取下一個command進行處理 result = talkWithDriver();// 來等待Client的請求 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) break; } while(result != -ECONNREFUSED && result != -EBADF); mOut.writeInt32(BC_EXIT_LOOPER); talkWithDriver(false); } ~~~ 這里的talkWithDriver()里面之際調用的是ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr)從/dev/binder讀取Client端發過來的請求,然后調用executeCommand處理 ~~~ status_t IPCThreadState::executeCommand(int32_t cmd) { BBinder* obj; RefBase::weakref_type* refs; status_t result = NO_ERROR; switch(cmd) { case BR_TRANSACTION: binder_transaction_data tr; result = mIn.read(&tr, sizeof(tr)); .... Parcel reply; if(tr.target.ptr) { sp<BBinder> b((BBinder*)tr.cookie); const status_t error = b->transact(tr.code, buffer, &reply, tr.flags); } .... break; } } 最后又調用到BBinder 的transact()函數里面去了。 status_t BBinder::transact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags ) { data.setDataPosition(0); switch(code) { case PING_TRANSACTION: reply->writeInt32(pingBinder()); break; default: err = onTransact(code, data, reply, flags); break; } return err; } ~~~ 到這里IPCThreadState類的流程就大概清楚了,線程調用joinThreadPool()從/dev/binder讀取客戶端的請求,然后調用 BBinder::transact()處理。那么這個BBinder是怎么來的呢? 上面代碼中:sp<BBinder> b((BBinder*)tr.cookie)說明這個BBinder指針是從Binder驅動中獲取到,肯定是客戶端發送過來的,那么它的實際類型又是什么呢?而BBinder調用的onTransact()函數只是一個虛函數,肯定由它的子類來實 現,那我們服務端又怎么找到這個BBinder的實際類型呢? 這些內容我們下一節通過MediaPlayer這個具體示例分析。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看