【新・言語進化論】次にくる!新登場言語
第4回:並列処理が可能な関数型言語「Erlang」
著者: オープンソース・ジャパン 須藤 克彦
公開日:2007/11/26(月)
Erlangの重要技術「並列処理」
Erlangで特に重要な技術が並列処理だ。
一般に、ハードウェア(例えば複数のハードディスク)が同時に動作することを「並列(パラレル:parallel)処理」と呼ぶ。これ対して、ソフトウェアがOSなどの制御によってあたかも「同時に動作するように見せる」ことを「並行(コンカレント:concurrent)処理」と呼ぶ。
この意味から、Erlangの並列処理は並行処理または「並行プログラミング(Concurrent Programming)」と呼ばれている。
Erlangではこの処理によって、複数のプログラムを同時に実行し、プログラム間で通信させることが可能だ。例としてリスト9のようなプログラムを取り上げる。
ここではプログラム全体よりも、「area_server」モジュールの「loop()」関数が、ずっとループをしながら他のプログラムから呼び出されるのを待っている、という部分だけを理解していてほしい。
ポイントは、「loop」という文があるのではなく、あくまで「loop()という関数を定義している」という点だ。receive〜end.の間で、受け取ったメッセージの形に応じて表示を行わせることができる。
リスト9:並列処理のサンプルプログラム
-module(area_server).
-export([loop/0]).
loop() ->
receive
{rectangle, Width, Height} ->
io:format("Area of rectangle is ~p~n", [Width * Height]),
loop();
{circle, R} ->
io:format("Area of circle is ~p~n", [3.141519 * R * R]),
loop();
Other ->
io:format("Error ~p~n", [Other]),
loop()
end.
リスト10:プロセスの生成
1> c(area_server).
{ok,area_server}
2> Pid = spawn(fun area_server:loop/0).
<0.37.0>
リスト11:Pidプロセスにメッセージを送信
3> Pid ! {rectangle, 5, 12}.
{rectangle,5,12}Area of rectangle is 60
リスト12:Pidプロセスに別の引数を指定してメッセージを送信
4> Pid ! {circle, 7}.
{circle,7}Area of circle is 153.934
5> Pid ! {triangle, 3,4,5}.
{triangle,3,4,5}Error {triangle,3,4,5}
リスト10のspawn()でプロセスを生成している。PidにはそのプロセスIDが設定されているが、これはOSレベルのものではなく、あくまでErlang内部のものとなっている。
リスト11ではPidのプロセスにメッセージを送るために「Pid ! {メッセージ}」を実行したところだ。「!」がメッセージの「送信」を表している。またリスト12のように他の引数を送信し、表示させることもできる。
これらは非常に簡単なクライアント/サーバの例で、area_serverというサーバ・プロセスに対してメッセージを送って処理を行わせている。ここでは並行動作する2つのプロセスが情報をやり取りできる、ということを理解してほしい。
プログラム(関数やサブルーチン)が互いに呼び合うものを「co-routine」と呼び、これについてはかつて「Modula」などの言語処理系が実装していた。プログラム間での通信はOSレベルのプロセスやスレッドで実装されるのが一般的なのだが、Erlangではこれを言語処理系の中で処理している。つまり、OSレベルのプロセス間通信よりも、はるかに「軽い」というメリットが生じるのである。
最後に
今回はErlangの特徴のほんの一部しか紹介できなかったが、並行処理をはじめとした魅力の一端だけでもお伝えできたのではないだろうか。
「母国語しか知らない者は母国語すら知らない」といったのはゲーテだが、筆者はプログラミング言語についても同様のことがいえると考えている。違うプログラム言語を学んでみることによって、改めていつも使っている言語の本質がみえてくるかもしれない。この機会にErlangに接してみてはいかがだろうか。 タイトルへ戻る