Erlang World


top > concurrent programming > spawn

Spawn

並列処理の開始

Erlangのプロセスについてどのようなものか分かって頂けたと思うので、この節では実際にプログラミングを通して 並列処理を行なってみましょう。

まずは、新しくプロセスをスタートさせる方法を学びます。
これはspawnという関数を使うことによって可能となります。

とりあえず、実際に手を動かして確認していきましょう。
まずは実験で利用するプログラムを確認してみます。

-module(spawn_test).
-export([say_something/2,sec_start/0, con_start/0]).

say_something(_What, 0) ->
    done;
say_something(What, Times) ->
    io:format("~p~n", [What]),
    say_something(What, Times - 1).

sec_start() ->
    say_something(hello,3),
    say_something(goodbye,3).

con_start() ->
    spawn(spawn_test, say_something, [hello, 3]),
    spawn(spawn_test, say_something, [goodbye, 3]).

con_start/0の中でspawn()が使われていますね。

まずはspawnで利用される関数である say_something/2 から見ていきます。

> spawn_test:say_something(hello,3).
hello
hello
hello
done

引数1で指定したものを、引数2で指定した回数だけ表示するのですね。 返り値はdoneです。

逐次プログラミング(sec_start/0)と、並列プログラミング(con_start/0)の違いを試してみましょう。 細かいspawn()関数の使いかたは後ほど扱いますが、今回はsay_something/2を利用しています。。

> spawn_test:sec_start().
hello
hello
hello
goodbye
goodbye
goodbye
done
> spawn_test:con_start().
hello
goodbye
<0.35.0>
hello
goodbye
hello
goodbye

結果が異なっていますね。
逐次プログラミングは hello と3回出力した後 goodbye と3回出力しています。

それに対して、並列プログラミングは hello と goodbye の出力が入り乱れています。
<0.35.0>は後ほど扱いますが、プロセス識別子(Pid)です。これは関数con_start/0の返り値です。

逐次プログラミングは順番に実行しているのに対し、並列プログラミングは
say_something(hello,3) と
say_something(goodbye,3)
が同時に実行されているため、このような結果になったのです。。

spawn関数

spawn関数が並列処理を始めることが分かったと思うので、詳細に見ていきます。

次の関数があるとしましょう。

module:function(Var1,Var2)

spawn関数の使い方は、次の2通りあります。

Pid1 = spawn(module, function, [Var1, Var2]).

Pid2 = spawn(fun() -> module:function(Var1,Var2) end).

上のタイプは引数として、「モジュール名、関数名、引数群」を渡しています。
引数群はリストで渡します。

下のタイプは fun として関数を渡しています。

プロセスの左にある変数は何を受け取っているかというと、プロセス識別子を受け取っています。
spawn関数を使って新しくプロセスを開始すると、その識別子を返すのです。

プロセス識別子はプロセスを特定するような番号のようなものです。 これはプロセスの通信の際のアドレスとしての役割を持っています。 詳しいことは次節以降で扱います。


Yuichi ITO. All rights reserved.
mail to : ad
inserted by FC2 system