DX・デジタルトランスフォーメーション

AppStoreにて無料公開中! ”システム手帳”で検索! - AppStoreへ iPad版 - iPhone版

ブロックチェーン・暗号技術 | android | iOS | Web | アプリの著作権 | 日本のなりたち | 禅・大乗仏教 | 新しい社会

スマホアプリにおけるプロセス(スレッド)間通信方法

スマホアプリにおけるプロセス(スレッド)間通信方法

プロセスとスレッドはそのコンテキストを共有するかどうかが異なるだけで、同一時間に複数の手続きを実行させるということにおいて概念的には同じである。

スレッド間で通信を行うには次の方法がある。

どの方法も50年前にC言語とともに生まれた偉大なOSであるUnixから実装されているレガシーな方法である。

・共有メモリ

POSIX標準の共有メモリはiOS、androidともに使用できない。

スレッド間であれば、インスタンス変数を共有することができる。

iOS

セマフォと合わせて使い、インスタンス変数(ヒープ領域)を共有する。

POSIX標準のshmget()等は使用できないため、アプリ間で共有するには、カスタムURLスキームやApp Groups#NSUserDefaultsやUIPasteboardなどのCocoaフレームワークで用意されている仕組みを利用する必要がある。

android

インスタンス変数が格納されるヒープメモリのGC(ガーベージコレクション)の影響やヒープメモリキャッシュの影響などによりThread間でメモリ領域を共有する際に想定外の動作をする場合があるので注意が必要となる。

・セマフォ

iOS

mSemaphoreForTerminate = dispatch_semaphore_create(0);dispatch_semaphore_signal(mSemaphoreForTerminate);

android

mSemaphoreForTerminate = new Semaphore(0);
mSemaphoreForTerminate.release();


・シグナル

try catch構文でエラー手続きに活用されているシグナルだが、本来はプロセス間通信のために作られた機能である。

スレッド間通信で用いるには、OSがSIG...として定義していないシグナル領域を用いる。

iOS

NSCondition#signal

android

使用できない

・androidフレームワークで用意されているスレッド間通信方式

スレッドとServiceConnectionをbindServiceで関連づけ、Messengerで双方向のスレッド間通信を実現する。

android

android#content#ServiceConnection    // 送受信のInlet Outletandroid#content#ContentWrapper#bindServiceandroid#os#Message msg = Message.obtain();
msg.arg1 = NOTIFICATION;
msg.replyTo = SelfMessenger;
android#os#Messenger#send(msg);


・ソケット

iOS

iOSではPOSIX標準ソケットとCocoaフレームワークのソケットが利用できる。

1) POSIX socket

int ipv4_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);if (bind(listen_sock, (struct sockaddr *)&sin, sizeof(sin)) < 0)listen()

2) CFSocket

CFSocketRef myipv4cfsock = CFSocketCreateCFRunLoopAddSource()

android

Socket socket = new Socket();socket.connect(new InetSocketAddress(IP_SERVER, SOCKET_SERVER), CONNECT_TIMEOUT);OutputStream outputStream = socket.getOutputStream();// リクエスト送信byte[] requestBuffer = "Request String".getBytes("UTF-8");outputStream.write(requestBuffer, 0, requestBuffer.length);// リクエスト受信while(true) {    String requestString = readSocket(socket, inputStream, outputStream);}