본문 바로가기
프로그래밍 놀이터/안드로이드, Java

Efficient Android Threading #3 프로세스 간 통신

by 돼지왕 왕돼지 2018. 3. 19.
반응형

Efficient Android Threading #3 프로세스 간 통신


이 글은 Efficient Android Threading 의 일부 내용만 발췌한 내용입니다.

자세한 내용은 책을 구입해서 보세용.

.aidl, AIDL, android interface definition language, Argument, binder, binder class, binder framework, binder thread pool, blocking, Callback, client, communication contract, constructor, Efficient Android Threading #3 프로세스 간 통신, getbinder, graph, ibinder, ibinder.flag_oneway, inout, IPC, Marshalling, message, messenger, onBind, oneway, oneway interface, oneway method, ontransact, out, parcel, Parcelable, Picture, proxy, replyto, RPC, Serializable, server connection, Service, STUB, transact, transaction, unmarshalling, void, 결과값, 단방향 통신, 동기식 rpc, 동기적, 마샬링, 메서드 데이터 분해, 메소드 호출, 메시지, 메신저, 메신저 참조, 바인더, 바인더 스레드, 바인더 스레드 풀, 바인더 프레임워크, 바인더를 이용한 메시지 전달., 반환값 전송, 비동기식 rpc, 서버, 서버 프로세스, 송신 프로세스, 수신 프로세스, 스레드 안전, 스텁, 안드로이드 RPC, 안드로이드 인터페이스 정의 언어, 양방향, 양방향 통신, 양방향 통신 메커니즘, 언마샬링, 원격 메서드 호출, 원격 프로세스, 원격 프로시저 호출, 자바 코드 생성, 재구성, 전송, 즉시 반환, 차례대로 테스크 실행, 최대 스레드 갯수, 콜백, 클라이언트, 테스크, 통신 계약, 트랜잭션, 프로세스, 프록시


5.1. 안드로이드 RPC


-

안드로이드의 변형 리눅스 커널 안에서, 리눅스 IPC 기술은 프로세스 사이의 RPC 메커니즘을 수행하는 바인더 프레임워크로 대체되었다.

이를 통해 클라이언트 프로세스는 마치 로컬에서 메서드를 실행하듯 서버 프로세스의 원격 메서드를 호출할 수 있다.



-

RPC 메서드 호출 자체는 단순하지만,  RPC 매커니즘의 하부는 다음과 같은 단계로 구성된다.


1. 메서드 데이터 분해(마샬링, marshalling)

2. 원격 프로세스로 마샬링된 정보를 전송

3. 원격 프로세스에 정보를 재구성(언마샬링, unmarshalling)

4. 원래 프로세스로 반환값을 전송



-

안드로이드 앱 프레임워크와 코어 라이브러리는 바인더 프레임워크와 안드로이드 인터페이스 정의 언어(AIDL, Android Interface Definition Language)를 통해 프로세스 통신을 추상화한다.




** 5.1.1. 바인더


-

원격 바인더는 앱들이 서로 다른 프로세스에서 실행하는 스레드들끼리 함수와 데이터(메소드 호출)를 보낼 수 있게 한다.

서버 프로세스는 Binder 클래스에서 지원되는 원격 인터페이스를 정의하고, 클라이언트 프로세스 안의 스레드는 원격 객체를 통해 이 원격 인터페이스에 접근할 수 있다.



-

함수와 데이터 모두를 전송하는 원격 프로시저 호출을 트랜잭션(transaction)이라고 부른다.

클라이언트 프로세스가 transact 메서드를 호출하면 서버 프로세스는 onTransact 메서드로 그 호출을 받는다.



-

transact 를 호출하는 클라이언트 스레드는 기본적으로 원격 스레드에서 onTransact 메서드의 실행이 완료될 때까지 차단된다.

트랜잭션 데이터는 프로세스 사이의 전송을 위한 바인더에 의해 최적화된 Parcel 객체로 구성된다.

인수(argument)와 반환값은 Parcel 객체로 전송된다.

Parcel 객체는 리터럴 인수와 Parcerlable 을 구현한 커스텀 객체를 포함한다.

Parcelable 인터페이스는 Serializable 보다 효율적인 방법으로 마샬링, 언마샬링을 정의한다.



-

onTransact 메서드는 바인더 스레드 풀에 속한 스레드에서 실행된다.

이 풀은 다른 프로세스에서 들어오는 요청을 처리하기 위해서만 존재한다.

최대 16개의 스레드를 가지므로, 모든 프로세스에서 16개 원격 호출이 동시에 처리될 수 있다.

물론 스레드 안전을 보장하는 호출의 구현이 필요하다.



-

IPC 는 양방향으로 동작할 수 있다.



-

서버 프로세스가 onTransact 를 수행하는 도중에, 서버 프로세스에서 클라이언트 프로세스에 요청을 보내는 transact 를 호출하면, 클라이언트 프로세스는 해당 요청을 바인더 스레드로 받지 않고, 서버로 onTransact 를 호출한 해당 thread 에서 첫번째 요청이 끝나기를 기다렸다가 해당 요청을 처리한다.



-

바인더는 IBinder.FLAG_ONEWAY 를 설정함으로써 비동기 트랜잭션을 지원한다.

이 플래그를 설정하면 클라이언트 스레드는 transact 를 호출하고 즉시 반환한다.

바인더는 서버 프로세스 안의 바인더 스레드에서 onTransact 호출을 계속하지만, 해당 클라이언트 스레드로 어떤 데이터를 동기적으로 반환 할 수 없다.







5.2. AIDL


-

어떤 프로세스가 다른 프로세스에서 접근할 수 있도록 기능을 노출하고 싶을 때는 통신 계약(communication contract)을 정의해야 한다.

기본적으로 서버는 클라이언트가 호출할 수 있는 메서드의 인터페이스를 정의해놓는다.



-

안드로이드 인터페이스 정의 언어(AIDL)의 인터페스를 기술하는 가장 간단하고 일반적인 방법은 .aidl 파일에 정의하는 것이다.

AIDL 파일을 컴파일하면 IPC 를 지원하는 자바 코드를 생성한다.


이렇게 생성된 자바 인터페이스는 모든 클라이언트 앱과 서버 앱에 포함된다.

인터페이스 파일은 데이터의 마샬링, 언마샬링뿐만 아니라 트랜잭션까지 다루는 proxy 와 stub 두 개의 내부 클래스를 정의한다.


AIDL 의 생성은 자동으로 바인더 프레임워크를 감싸는 자바 코드를 생성하고 통신 계약을 설정한다.



-

.aidl, AIDL, android interface definition language, Argument, binder, binder class, binder framework, binder thread pool, blocking, Callback, client, communication contract, constructor, Efficient Android Threading #3 프로세스 간 통신, getbinder, graph, ibinder, ibinder.flag_oneway, inout, IPC, Marshalling, message, messenger, onBind, oneway, oneway interface, oneway method, ontransact, out, parcel, Parcelable, Picture, proxy, replyto, RPC, Serializable, server connection, Service, STUB, transact, transaction, unmarshalling, void, 결과값, 단방향 통신, 동기식 rpc, 동기적, 마샬링, 메서드 데이터 분해, 메소드 호출, 메시지, 메신저, 메신저 참조, 바인더, 바인더 스레드, 바인더 스레드 풀, 바인더 프레임워크, 바인더를 이용한 메시지 전달., 반환값 전송, 비동기식 rpc, 서버, 서버 프로세스, 송신 프로세스, 수신 프로세스, 스레드 안전, 스텁, 안드로이드 RPC, 안드로이드 인터페이스 정의 언어, 양방향, 양방향 통신, 양방향 통신 메커니즘, 언마샬링, 원격 메서드 호출, 원격 프로세스, 원격 프로시저 호출, 자바 코드 생성, 재구성, 전송, 즉시 반환, 차례대로 테스크 실행, 최대 스레드 갯수, 콜백, 클라이언트, 테스크, 통신 계약, 트랜잭션, 프로세스, 프록시

클라이언트 프록시(proxy)와 서버 스텁(stub)은 서버 프로세스(더 정화하게는 서버 내 스레드 풀에 속한 바인더 스레드) 안에서 실행되더라도 클라이언트가 지역적으로 메서드를 호출하도록 허용하는 두 앱을 대신하여 RPC 를 관리한다.




* 5.2.1. 동기식 RPC


-

클라이언트는 특정 동기식 원격 메서드 호출의 수명이 짧다고 해서 UI 스레드에서의 호출이 안전하다고 단정하면 안 된다.

서버 프로세스 구현은 시간에 따라 달라질 수 있고 UI 스레드의 반응성에 부정적인 영향을 미칠 수 있다.

따라서 원격 메서드 실행이 제어되지 않으면 원격 메서드 호출을 위해 클라이언트 작업자 스레드를 사용하라.




* 5.2.2. 비동기식 RPC


-

클라이언트가 자신의 비동기식 정책을 구현하게 하는 대신, 모든 원격 메서드 호출이 비동기적으로 실행되도록 정의하는 것이 좋다.

클라이언트 스레드는 비동기식 RPC 로 트랜잭션을 시작하고 즉시 반환한다.

바인더는 서버 프로세스로 트랜잭션을 제공한 다음 클라이언트에서 서버로의 연결을 닫는다.

비동기 메서드는 반드시 void 를 반환해야 하며, out 또는 inout 으로 선언된 인수가 없어야 한다.

결과값을 얻기 위해선 콜백 구현을 사용한다.



-

비동기식 RPC 는 oneway 키워드를 붙여 AIDL 안에 정의하며, 인터페이스 단계나 개별 메서드에적용될 수 있다.

oneway interface IAsyncInterface {

    void method1();

    void method2();

}


interface IAsyncInterContainingInterface{

    oneway void method1();

    void method2();

}



-

비동기식 RPC 의 가장 간단한 형태는 메서드 호출 시 콜백 인터페이스를 정의하는 것이다.

콜백 인터페이스 정의 역시 AIDL 에 한다.





5.3. 바인더를 이용한 메시지 전달.


-

원격 프로세스로 Message 를 보내기 위해서는 Messenger 를 사용할 수 있다.


.aidl, AIDL, android interface definition language, Argument, binder, binder class, binder framework, binder thread pool, blocking, Callback, client, communication contract, constructor, Efficient Android Threading #3 프로세스 간 통신, getbinder, graph, ibinder, ibinder.flag_oneway, inout, IPC, Marshalling, message, messenger, onBind, oneway, oneway interface, oneway method, ontransact, out, parcel, Parcelable, Picture, proxy, replyto, RPC, Serializable, server connection, Service, STUB, transact, transaction, unmarshalling, void, 결과값, 단방향 통신, 동기식 rpc, 동기적, 마샬링, 메서드 데이터 분해, 메소드 호출, 메시지, 메신저, 메신저 참조, 바인더, 바인더 스레드, 바인더 스레드 풀, 바인더 프레임워크, 바인더를 이용한 메시지 전달., 반환값 전송, 비동기식 rpc, 서버, 서버 프로세스, 송신 프로세스, 수신 프로세스, 스레드 안전, 스텁, 안드로이드 RPC, 안드로이드 인터페이스 정의 언어, 양방향, 양방향 통신, 양방향 통신 메커니즘, 언마샬링, 원격 메서드 호출, 원격 프로세스, 원격 프로시저 호출, 자바 코드 생성, 재구성, 전송, 즉시 반환, 차례대로 테스크 실행, 최대 스레드 갯수, 콜백, 클라이언트, 테스크, 통신 계약, 트랜잭션, 프로세스, 프록시


메시지는 메신저를 이용해 다른 프로세스 내 스레드로 보내질 수 있지만, 송신 측 프로세스(클라이언트)는 수신 측 프로세스(서버)에서 메신저의 참조를 가져올 수 있다.




** 5.3.1. 단방향 통신


-

Service 의 onBind 에서는 Messenger 의 getBinder 를 호출하여 return 해주고,

Client 에서는 Server connection 결과로 전달받은 IBinder 를 Messenger 의 constructor 로 전달해줌으로서 연결이 완성된다.




** 5.3.2. 양방향 통신


-

프로세스 간에 전달되는 메시지는 발신 프로세스 안에 Message.replyTo 의 인수로 전달되는 메신저 참조를 유지한다.

이 참조는 다른 프로세스에서 두 스레드 간의 양방향 통신 메커니즘을 만드는 데 사용될 수 있다.



-

바인더 스레드에서 동시에 테스크를 실행할 수 있는 AIDL 과 달리, 메신저는 설계상 차례대로 테스크를 실행한다.






반응형

댓글0