2011.04.14 01:34

Android의 모든 Component는 main thread에서 동작하는 이유는 무엇인가?


 

Processes and Threads 

When an application component starts and the application does not have any other components running, the Android system starts a new Linux process for the application with a single thread of execution. By default, all components of the same application run in the same process and thread (called the "main" thread). If an application component starts and there already exists a process for that application (because another component from the application exists), then the component is started within that process and uses the same thread of execution. However, you can arrange for different components in your application to run in separate processes, and you can create additional threads for any process.

This document discusses how processes and threads work in an Android application.


http://d.android.com/guide/topics/fundamentals/processes-and-threads.html

By default, all components of the same application run in the same process and thread(called the "main" thread).


android는 platform이다.
그 안에 activity, service, receiver, content provider라는 4 종류의 component들이 서식한다. 각 component는 각자의 생명주기를 가지며, 태어나고, 사용되고, 죽는다. activity manager가 해당 component들의 생명주기를 담당한다.

android는 linux kernel을 사용한다.
android는 linux의 process와 thread모델을 사용하여 platform의 runtime architecture를 디자인하였다.
- 하나의 application은 하나의 process에서 구동된다.
- 각 process마다 별도의 dalvik vm이 존재한다. 이는 자바의 특성이지만, android가 linux process, thread 모델을 채용하여 여러 application이 각자의 process에서 동작되어 core java library에서 서로 공유해야하는 정보는 property service로 해결해야하는 상황이다(얻는게 있으면 잃는게 있는 법).
- 각 process에선 위 component가 main thread에서 동작한다.
- activity manager는 system process에서 수행된다. 

android는 binder IPC를 만들었다.
32 bits linux kernel은 각 process마다 4GB의 메모리 주소 공간을 부여한다. 각 process간에는 해당 메모리는 보호되어 서로 통신하기 위해서는 각종 IPC를 사용해서 통신해야한다. 그 이유는 한 process의 오류가 다른 process까지 영향을 주지 않도록 하기 위한 것이다.
- android는 binder를 통해 process들이 서로 원격의 함수를 마치 함수 호출처럼 사용하여 타이밍 문제가 없도록 block된다 (non block 방식도 존재하는지는 모르겠다).
- process가 binder IPC를 통해서 전달받은 메시지는 main thread가 아닌 별도의 binder thread에서 실행된다. binder thread는 pool로 관리되어 여러개의 binder 메시지를 받을 수 있다.

android는 CPU와 메모리가 제약이 심한 mobile platform이다.
linux kernel의 OOM(Out Of Memory)는 process의 우선순위를 선택하여 메모리 부족시 강제로 process를 종료한다. 이 우선순위는 사용자 친화적이지 않은 단점이 있다.
android의 activity manager는 사용자에게 중요한 순서로 process의 우선순위를 지정한다.
android는 low memory killer를 linux kernel에 추가하여 현재 가용 메모리 량에 따라 process를 종료를 수행한다.
사용자는 해당 process가 종료되었다가 다시 살아났는지 알수 없도록 그 상태를 저장했다가 복원해주는 기능을 제공한다.


난 service가 일반적으로 말하는 background에서 처리해야하는 것으로 생각하여 당연히 main thread가 아닌 별도의 thread를 만들어서 처리되는 것으로 오해하고 있었다.

위 링크의 내용처럼 기본적으로 모든 component는 main thread에서 수행된다. 그 이유가 무엇일까?

1. 모든 component의 기본 동작은 main thread에서 수행된다.
2. 원격 process의 binder 요청은 별도의 binder thread를 통해서 받는다.
android의 runtime architecture는 이 2개가 전부다. 얼마나 단순한가? 이 것이 그 첫번째 이유다.

1번 항목에서 service의 main thread에서 수행되는 이유는 activity manager는 해당 service가 별도 thread로 동작하여 뭔가를 처리하길 기다리거나 하지 않는다. 그 책임은 모두 application 개발자에게 부여된다. 얼마나 단순한가? 이 것이 그 두번째 이유다.

activity manager는 startService(), stopService()와 같은 요청을 받아 service가 수행될 process를 생성하고 service가 시작되고 종료될 수 있도록 메시지를 process에 전달하고 해당 service의 생명주기 정보는 activity manager가 관리한다. 그래야 해당 service가 수행 중인 process의 우선순위를 알수 있고 그래야 activity manager가 process의 우선순위를 조정하여, low memory killer가 특정 상황에서 정상 동작할 수 있도록 하는 platform 자체의 생명주기를 완성하게 된다. 이부분이 service가 main thread에서 동작하는 이유가 되기엔 애매한 느낌이 든다.

어쨋든 activity manager는 4종류의 component가 application process에서 생성/사용/파괴 될 수 있도록 기본 구조를 제공한다. activity manager의 runtime architecture의 관점에선 4종류의 component를 구분하는 것은 의미가 없다.

android는 복잡한 runtime architecture를 채용하기 보단 각자의 역할을 잘 구분하여 디지인되어 있다고 보는게 타당하다고 생각된다. system process에서 동작하는 activity manager는 application process에게 4종류의 component의 생성/사용/파괴 될 수 있도록 무조건 main thread로 전달해준다. application process에서 어떻게 해당 component가 별도의 thread에서 동작할 지는 application 개발자에게 분담 시킨 것이다.

그 기반에는 binder IPC가 binder thread에서 코드가 동작되어 process는 main thread이외에도 binder thread를 가질 수 있었기 때문에 이런 간단한(?) 구조가 가능했던 것으로 사료된다. 처음부터 이 구조를 채용하기 위해서 binder의 thread 사용방식이 디자인 되었겠지만....

   














 
Trackback 4 Comment 0