Binder 스 레 드, Binder 메 인 스 레 드, Client 요청 스 레 드 의 개념 과 차이

Binder 스 레 드 는 Binder 서 비 스 를 수행 하 는 캐리어 로 서버 에 만 의미 가 있 습 니 다. 요청 단 에 있어 Binder 스 레 드 를 고려 할 필요 가 없 지만 Android 시스템 의 처리 체 제 는 대부분 C / S 입 니 다.예 를 들 어 앱 과 AMS 가 상호작용 을 할 때 모두 상대방 의 C 와 S 인 데 여기 서 이 문 제 를 토론 하지 않 고 Binder 스 레 드 의 개념 을 먼저 본다.
바인더 스 레 드
Binder 스 레 드 는 Binder 실체 업 무 를 수행 하 는 스 레 드 입 니 다. 일반적인 스 레 드 는 어떻게 해야만 Binder 스 레 드 가 될 수 있 습 니까?간단 합 니 다. Binder 문자 장 치 를 감청 하 는 Loop 스 레 드 를 켜 면 됩 니 다. Android 에 서 는 여러 가지 방법 이 있 지만 결국은 Binder 를 감청 하 는 것 입 니 다. 코드 로 바 꾸 면 ioctl 을 통 해 감청 하 는 것 입 니 다.
ServerManager 프로 세 스 를 보면 그 메 인 라인 은 Binder 라인 이 고 그 방법 은 binder 를 통 해loop 불사 스 레 드 구현:
void binder_loop(struct binder_state *bs, binder_handler func)
{
   ...
    for (;;) {
    <!--   1-->
        res = ioctl(bs->fd, BINDER_WRITE_READ, &bwr);
     <!--   2-->
        res = binder_parse(bs, 0, readbuf, bwr.read_consumed, func);
        。。
    }
}

위의 관건 적 인 코드 1 은 감청 클 라 이언 트 의 요청 을 막 는 것 이다. 2 는 요청 을 처리 하 는 것 이 고 이것 은 순환 이 며 종료 하지 않 는 다.SystemServer 프로 세 스 의 스 레 드 를 살 펴 보면 Android 4.3 (6.0 이후 코드 가 다 릅 니 다) 에서 SystemSever 메 인 스 레 드 는 바로 Binder 스 레 드 입 니 다. 같은 Binder 메 인 스 레 드 입 니 다. Binder 스 레 드 와 Binder 메 인 스 레 드 의 차 이 는 스 레 드 가 Loop 을 종료 할 수 있 는 지 여부 입 니 다. 그러나 현재 시작 하 는 Binder 스 레 드 는 모두 종료 할 수 없습니다. 사실은 모두 Binder 메 인 스 레 드 라 고 볼 수 있 습 니 다.그 실현 원 리 는 SystemServer 메 인 스 레 드 가 마지막 까지 실 행 될 때 Loop 이 Binder 장 치 를 감청 하고 순환 스 레 드 로 변신 하 는 것 이다. 관건 적 인 코드 는 다음 과 같다.
extern "C" status_t system_init()
{
    ...
    ALOGI("System server: entering thread pool.
"
); ProcessState::self()->startThreadPool(); IPCThreadState::self()->joinThreadPool(); ALOGI("System server: exiting thread pool.
"
); return NO_ERROR; }

ProcessState:: self () - > startThreadPool () 은 Binder 메 인 스 레 드 를 새로 만 듭 니 다.
그리고 PCThreadState:: self () - > joinThreadPool () 은 현재 스 레 드 를 Binder 메 인 스 레 드 로 바 꿉 니 다.
사실 startThreadPool 은 최종 적 으로 join ThreadPool 을 호출 하여 관건 적 인 함 수 를 보 겠 습 니 다.
void IPCThreadState::joinThreadPool(bool isMain)
{
    ...
    status_t result;
    do {
        int32_t cmd;
        ...   1 
        result = talkWithDriver();
        if (result >= NO_ERROR) {
           ...   2 
            result = executeCommand(cmd);
        }
        //          
        if(result == TIMED_OUT && !isMain) {
            break;
        }
        //    ,   ,     ,       Binder    ,
    } while (result != -ECONNREFUSED && result != -EBADF);
 }

status_t IPCThreadState::talkWithDriver(bool doReceive)
{  
    do {
        ...   3 
        if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
   }   

관건 점 1 talk With Driver 를 살 펴 보면 실질 적 으로 ioctl (mProcess - > mDriverFD, BINDER WRITE READ, & bwr) > = 0) 을 사용 하여 Binder 문자 장 치 를 계속 감청 하고 Client 가 전송 하 는 데 이 터 를 얻 은 다음 에 executeCommand 를 통 해 해당 하 는 요청 을 수행 합 니 다. join ThreadPool 은 일반 스 레 드 화신 Binder 스 레 드 에서 가장 흔히 볼 수 있 는 방식 입 니 다.못 믿 겠 으 면 미디어 서비스 하나 더 보고 mainmediaserver 의 main 함수:
int main(int argc, char** argv)
{
   。。。
        sp<ProcessState> proc(ProcessState::self());
        sp<IServiceManager> sm = defaultServiceManager();
        ALOGI("ServiceManager: %p", sm.get());
        AudioFlinger::instantiate();
        MediaPlayerService::instantiate();
        CameraService::instantiate();
        AudioPolicyService::instantiate();
        registerExtensions();
        ProcessState::self()->startThreadPool();
        IPCThreadState::self()->joinThreadPool();
    }

사실은 join ThreadPool 을 통 해 Binder 스 레 드 로 변신 하 였 습 니 다. 메 인 스 레 드 인지 아 닌 지 는 아래 의 함 수 를 보 세 요.
void IPCThreadState::joinThreadPool(bool isMain)

void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        String8 name = makeBinderThreadName();            
        ALOGV("Spawning new pooled thread, name=%s
"
, name.string()); sp<Thread> t = new PoolThread(isMain); t->run(name.string()); } }

사실 관건 은 join ThreadPool 함수 에 전 달 된 isMain 이 true 인지 아 닌 지 하 는 것 입 니 다. 그러나 Binder 메 인 스 레 드 인지 아 닌 지 는 아무 소 용이 없습니다. 소스 코드 에 이 두 가지 서로 다른 처 리 를 위해 입 구 를 남기 지 않 았 기 때문에 관심 이 있 으 면 binder 의 TIMED 를 살 펴 보 세 요.OUT。

좋은 웹페이지 즐겨찾기