SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

japan.internet.com翻訳記事

Erlangを使った並列処理プログラムの作成

マルチコアCPUを最大限活用する方法

ダウンロード サンプルソース (1.2 KB)

プロセス間通信

 Erlangでは、異なるプロセス同士は何も共有せず、それぞれのプロセスは完全に分離しています。プロセス間の通信手段はメッセージだけです。前述のように、products_collectorプロセスは、(1) 各partial_compute関数から(それぞれの計算の完了時)、および(2)関数computeから(すべてのpartial_compute関数が終了し、結果のリストを要求しているとき)、メッセージを受け取ります。この2つの場合のメッセージ送信の構文は以下のとおりです。

シナリオ1
ProductsCollector_PID ! {get_products,self()},
シナリオ2
ProductsCollector_PID ! {add_product,multiplication(FactorsInTheInterval)}.

 どちらの場合も、送信するメッセージは、メッセージの送信先プロセスのPID、演算子!、タプル形式のメッセージ本体で構成されます。たとえば、シナリオ1のメッセージ本体には、アトムget_productとメッセージの送信元プロセスのPIDが含まれます。送信元プロセスのPIDは、送信したメッセージに対して送信先プロセスから応答を受け取るときに必要になります。

 送信されたメッセージはすべて非同期なので、プログラムは応答を待たず(応答が来る予定の場合)、即座にその次の命令を実行します。

 次に、関数products_collectorで、プロセスがメッセージの到着を待機してアクションを実行する方法を見てみましょう。

products_collector(L, Loop_PID) ->
    receive
        {add_product, Product} ->
            Loop_PID ! {done},
            products_collector([Product|L], Loop_PID);
        {get_products, Client_PID} ->
            Client_PID ! {products, L},
            products_collector(L, Loop_PID);
        {done} ->
            noop
    end.

 電子メールにたとえると、プロセスには受信箱があり、着信メッセージはすべてキューに入れられ、FIFO方式とパターンマッチングメカニズムを使って処理されます。

 こうした仕組み全体を理解するには、receive ... end構造を理解することがとても重要です。着信メッセージのキューと、各種パターンを表すタプル一式があるとします。新しいメッセージが届いたとき、そしてそのときのみ、以下のことが発生します。

 まず、キュー内の最初のメッセージ(最初に到着したメッセージ)が最初のパターンとマッチングされます。

  • マッチした場合:その次の文が実行されます。そのメッセージはキューから削除されます
  • マッチしなかった場合:そのメッセージが次のパターンとマッチングされます

 最初のメッセージがリスト内のどのパターンとも一致しなかった場合は、

  • そのメッセージは「退避キュー」というキューへ入れられ、2番目のメッセージの処理へ進みます
  • 退避キュー内のメッセージは、新しいメッセージが着いた後も、もうマッチングされません

 receive ... end構造の追加機能の1つとしてタイマーがあります。これは、新しいメッセージの待機を一定時間後に中止し、なんらかのアクションを実行してから、退避キュー内のメッセージをメールボックスに元の順番どおりに戻します。

Debian Linuxでコードを実行するには

 1998年、Ericsson社はErlangをオープンソース製品として公開し、WebサイトErlang.orgを開設しました。このサイトでは、コードのほか、Linux、Mac、Windows環境用のErlangインタープリタのバイナリも提供されています。コードダウンロードには、各種モジュールライブラリや、Mnesia(PDF)というリアルタイム分散データベースもあります。このフレームワーク全体をErlang Open Telecom Platform(OTP)と呼びます。

 Debian Linuxでは、以下のコマンドでインストールします。

apt-get install erlang

 ツールやユーティリティ関数も含めたErlang OTPプラットフォーム一式がこれでインストールされます。

 Erlangのコードをインタープリタ用擬似コードにするには、コンパイルして拡張子.beamのファイルにする必要があります。

erlc fact.erl

 コンパイラは、かなり冗長ですが分かりやすく、Erlangの考え方を理解するのに役立ちます。例えば、変数がバインドされないまま使用される場合には、それが検出されます。

 コンパイル後は、factモジュールでエクスポートされているすべての関数を実行できます。これによって、デバッグ時にどの関数が適切に動いていないかを調べることができ、とても便利です。対象環境でErlangエミュレータerlを実行し、次のように入力します。

Erlang R13B01 (erts-5.7.2) [source] [smp:2:2] [rq:2] [async-threads:0] [kernel-poll:false]

Eshell V5.7.2  (abort with ^G)
1>

 次のようにして、エミュレータ内でコードを再コンパイルできます。

c("fact.erl").

 通常、関数startがプログラム実行のmainを表します。

2> fact:start(2,12).
Time elapsed for factorial of 12 using 2 parallel processes: 1.45e-4 seconds
ok
2>

 2つ以上の並列プロセスを使って、大きな整数の階乗を計算してみてください。従来のCPUとマルチコアマシンでは、所要時間に違いがあることが分かるでしょう。

 前述のとおり、それぞれの関数も、エクスポートして適切な入力を指定すれば実行できます。

3> fact:compute(2,[123,234,456,345]).
4527984240
3>

4> fact:multiplication([123,234,456,345]).
4527984240
4>

 デバッガは次のようにして起動します。

Erlang R13B01 (erts-5.7.2) [source] [smp:2:2] [rq:2] [async-threads:0] [kernel-poll:false]

Eshell V5.7.2  (abort with ^G)
1> c("fact.erl",[debug_info]).
{ok,fact}
2> im().

3> ii(fact).
{module,fact}
4> iaa([init]).
true
5> fact:start(2,12).

 iで始まる文は、グラフィカルプロセスモニタと、ソースコードを表示する標準的デバッグウィンドウを開始します(図2と図3を参照)。もちろん、これらのウィンドウは、実行中に生成されたプロセスごとにオープンされます。

図2 プロセスモニタ:Erlangエミュレータで処理されるすべてのプロセスを追跡できるので便利。
図2 プロセスモニタ:Erlangエミュレータで処理されるすべてのプロセスを追跡できるので便利。
図3 デバッグウィンドウ:標準的なデバッグウィンドウ。Erlangエミュレータで生成されるプロセスごとに1つずつ起動できる。
図3 デバッグウィンドウ:標準的なデバッグウィンドウ。Erlangエミュレータで生成されるプロセスごとに1つずつ起動できる。

次のステップ:LYME

 これで、並列プロセスを連携し、同時実行させるErlangの仕組みについてご理解いただけたと思います。現在では、Erlangで開発された多くのアプリケーションが実際に使われています。Yahoo! del.icio.us、Facebookのチャットバックエンド、Twitterfall(Twitterのトレンド検索エンジン)、Amazon SimpleDBもそうです。その多くはマルチコアマシンの能力を活用しています。あなたのアプリケーションもその一員に加えましょう。Erlangを本格的に使うなら、LYME(Linux、Yaws、Mnesia、Erlang)ソリューションスタックが、機能的な並列処理ソリューション作成に優れた環境を提供します。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
japan.internet.com翻訳記事連載記事一覧

もっと読む

この記事の著者

japan.internet.com(ジャパンインターネットコム)

japan.internet.com は、1999年9月にオープンした、日本初のネットビジネス専門ニュースサイト。月間2億以上のページビューを誇る米国 Jupitermedia Corporation (Nasdaq: JUPM) のニュースサイト internet.comEarthWeb.com からの最新記事を日本語に翻訳して掲載するとともに、日本独自のネットビジネス関連記事やレポートを配信。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

Roberto Giorgetti(Roberto Giorgetti)

イタリアに拠点を置くITマネージャ、テクニカルライター。主にビジネス分野と工業分野でオープンソースの開発に従事。核工学の学位を持つ。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4486 2009/10/28 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー