バックグラウンドで働く「非同期」プログラミングの方法とは?

データのダウンロード処理や、大量のデータ計算処理など、メインの処理とは別に新しい処理系を作り処理を行うことを「バックグラウンドタスク」と表現することもあります。

バックグラウンドで処理する方法については言語ごとに方法も仕組みも異なっていますが、いくつかの言語を題材にバックグラウンドで処理を行う方法について見ていきましょう。

「バックグラウンド処理」の仕組み

メインの処理とは異なる処理系を立ち上げ、別系統の処理で「裏側」で処理を行うことを「バックグラウンド処理」と言います。

GUIなど、ユーザーの目に見える部分を「フォアグラウンド」、ユーザーの目に見えない処理を「バックグラウンド」と呼びますが、なぜこのような仕組みがあるのかと言うと、ユーザーの利便性を妨げないことが挙げられます。

すべての処理をフォアグラウンドで行うと、例えば、プリンターの印刷が終わるまで画面操作が行えなかったり、大容量のデータをコピーしている時に他の操作が行えないなどの「GUIロック」が発生してしまいます。

「GUIロック」は、ユーザーが画面上で一切の操作を行うことができなくなるため、ユーザーへの負担やストレスに繋がることも少なくありません。

そのため、ユーザーの操作を妨げないように画面制御とは別に処理系を作りそこで、他の処理を行うことを「バックグラウンド処理」と呼んでいます。

バックグラウンド処理

上図のように、画面制御処理を実行したまま、処理1・処理2など、他の処理も並行して行うことができます。

WindowsなどのOSも、複数のアプリケーションを起動・実行できるようにするために、このような処理系を持っており、「マルチタスク」と呼ばれています。

最近では、iOSなどのスマートデバイス向けOSでもこのようなマルチタスク機能が搭載されるようになっています。

では、具体的にどのようなところで、バックグランド処理が行われているのでしょうか?

これからいくつかの事例について見ていきましょう。

バックグラウンド処理・非同期処理の事例

バックグラウンド処理の仕組みを理解したところで、身近な事例についていくつかお話をしていきたいと思います。

Ajax(Asynchronous JavaScript + XML)

みなさんが普段よく使うソフトウェアの1つが「ブラウザ」ではないでしょうか。

実は、ブラウザの中でも通信処理などに非同期処理が使用されています。

近年のWEBサービス開発では、Javascriptプログラミングを行う際に「Ajax」と呼ばれる技術を使用することが一般的に行われており、画面制御を停止させずに、データ通信を非同期で行うことができます。

Ajaxの実際のプログラム例は下記からご参照ください。

→「第1回 PHPで簡単なAjaxプログラムを作ろう (その4)」

こちらの例では、Javascriptで「XMLHttpObject」または「Microsoft.XMLHTTP ActivexObject」を使用した実装となっていますが、現在では、JQUERYを用いたAjax処理を行う方法が広く使われています。

ということでこちらのJQUERY使用のJavascriptコードを使えるようになった方が良いでしょう。

→「jQueryでAjaxを始めよう! 」

いずれにしても内部的には同じことを行っていますが、こういう「非同期」の流れがメインストリームとなるのは自然な流れのような気がします。

「非同期処理を使い始めたら同期処理に戻れない」

と感じる人も少なからずいるのではないでしょうか。

スマートフォンアプリの非同期処理

スマートフォン用のアプリケーションでも、ブラウザと同じく非同期で処理を行うことも増え、SDKの進化ともにその方法も日々進化しています。

今回は、iPhoneアプリを事例に非同期通信の処理について見ていきましょう。

iPhoneアプリに搭載されているiOSでは、GCD(Grand Central Dispatch)を用いてマルチスレッド処理を実現しています。

他にもNSThreadを用いる方法など、さまざまな方法がありますが、非同期データ通信処理で利用されるのが「NSURLSession.dataWithURL」&「dispatch_async」です。

それでは、Swiftでの事例を元にプログラムの書き方を見ていきましょう。

let url = NSURL(string: "アクセス先のURL" as String)
					
// 非同期通信は「NSURLSession.dataWithURL」&「dispatch_async」を推奨 ////////////////
let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: sessionConfig)
let task_async = session.dataTaskWithURL(url!){
  (datas, response, error) in 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),{
      //バックグラウンド実行
      dispatch_async(dispatch_get_main_queue(), {
        //Main Threadで実行する処理を記述(非同期)
      });
  });
}
task_async.resume()

づらづらといろんなプログラムコードが並んでいますが、基本的にURLを指定して、そのURLのデータを受け取ったら非同期で処理するという流れなので、そんなに難しい内容ではありません。

しかし、iPhoneもSDKや言語の進化により、従来の方法がどんどん置き換えられていく状況が続きそうですので、より先進的な手法が開発されれば、この方法もいつまで使えるかはわかりません。

非同期処理はなんだか難しそうと思われていた方も非同期処理の概要をご理解いただけたのではないでしょうか。

ただし、非同期処理に頼りすぎることで、複雑な処理状況が多発してしまい把握困難な状況に陥ってしまうこともありますので、使いどころを考えて利用していく必要がある技術でもあります。

HOMEへ