资料来源:http://blog.bot.co.za/en/article/349/an-erlang-otp-tutorial-for-beginners#.Upo4SWSOGJY
代码如下:
src/hello_server.erl
%%%----------------------------------------------------------------------------
%%% @doc An OTP gen_server example
%%% @author Hans Christian v. Stockhausen <hc at vst.io>
%%% @end
%%%----------------------------------------------------------------------------
-module(hello_server). % Nothing new in this section except for the
% next line where we tell the compiler that
-behaviour(gen_server). % this module implements the gen_server
% behaviour. The compiler will warn us if
-define(SERVER, ?MODULE). % we do not provide all callback functions
% the behaviour announces. It knows what
-record(state, {count}). % functions to expect by calling
% gen_server:behaviour_info(callbacks). Try it.
%%-----------------------------------------------------------------------------
%% API Function Exports
%%-----------------------------------------------------------------------------
-export([ % Here we define our API functions as before
start_link/0, % - starts and links the process in one step
stop/0, % - stops it
say_hello/0, % - prints "Hello" to stdout
get_count/0]). % - returns the count state
%% ---------------------------------------------------------------------------
%% gen_server Function Exports
%% ---------------------------------------------------------------------------
-export([ % The behaviour callbacks
init/1, % - initializes our process
handle_call/3, % - handles synchronous calls (with response)
handle_cast/2, % - handles asynchronous calls (no response)
handle_info/2, % - handles out of band messages (sent with !)
terminate/2, % - is called on shut-down
code_change/3]). % - called to handle code changes
%% ---------------------------------------------------------------------------
%% API Function Definitions
%% ---------------------------------------------------------------------------
start_link() -> % start_link spawns and links to a new
gen_server:start_link( % process in one atomic step. The parameters:
{local, ?SERVER}, % - name to register the process under locally
?MODULE, % - the module to find the init/1 callback in
[], % - what parameters to pass to init/1
[]). % - additional options to start_link
stop() -> % Note that we do not use ! anymore. Instead
gen_server:cast( % we use cast to send a message asynch. to
?SERVER, % the registered name. It is asynchronous
stop). % because we do not expect a response.
say_hello() -> % Pretty much the same as stop above except
gen_server:cast( % that we send the atom say_hello instead.
?SERVER, % Again we do not expect a response but
say_hello). % are only interested in the side effect.
get_count() -> % Here, on the other hand, we do expect a
gen_server:call( % response, which is why we use call to
?SERVER, % synchronously invoke our server. The call
get_count). % blocks until we get the response. Note how
% gen_server:call/2 hides the send/receive
% logic from us. Nice.
%% ---------------------------------------------------------------------------
%% gen_server Function Definitions
%% ---------------------------------------------------------------------------
init([]) -> % these are the behaviour callbacks. init/1 is
{ok, #state{count=0}}. % called in response to gen_server:start_link/4
% and we are expected to initialize state.
handle_call(get_count, _From, #state{count=Count}) ->
{reply,
Count, % here we synchronously respond with Count
#state{count=Count+1} % and also update state
}.
handle_cast(stop, State) -> % this is the first handle_case clause that
{stop, % deals with the stop atom. We instruct the
normal, % gen_server to stop normally and return
State % the current State unchanged.
}; % Note: the semicolon here....
handle_cast(say_hello, State) -> % ... becuase the second clause is here to
io:format("Hello~n"), % handle the say_hello atom by printing "Hello"
{noreply, % again, this is asynch, so noreply and we also
#state{count=
State#state.count+1}
}. % update our state here
handle_info(Info, State) -> % handle_info deals with out-of-band msgs, ie
error_logger:info_msg("~p~n", [Info]), % msgs that weren't sent via cast
{noreply, State}. % or call. Here we simply log such messages.
terminate(_Reason, _State) -> % terminate is invoked by the gen_server
error_logger:info_msg("terminating~n"), % container on shutdown.
ok. % we log it and acknowledge with ok.
code_change(_OldVsn, State, _Extra) -> % called during release up/down-
{ok, State}. % grade to update internal state.
%% ------------------------------------------------------------------
%% Internal Function Definitions
%% ------------------------------------------------------------------
% we don't have any.
src/hello_sup.erl
-module(hello_sup).
-behaviour(supervisor).
%% API
-export([start_link/0]).
%% Supervisor callbacks
-export([init/1]).
%% Helper macro for declaring children of supervisor
-define(CHILD(I, Type), {I, {I, start_link, []}, permanent, 5000, Type, [I]}).
%% ===================================================================
%% API functions
%% ===================================================================
start_link() ->
supervisor:start_link({local, ?MODULE}, ?MODULE, []).
%% ===================================================================
%% Supervisor callbacks
%% ===================================================================
init([]) ->
RestartStrategy = one_for_one,
MaxRestarts = 1000,
MaxSecondsBetweenRestarts = 3600,
SupFlags = {RestartStrategy, MaxRestarts, MaxSecondsBetweenRestarts},
Restart = permanent,
Shutdown = 2000,
Type = worker,
AChild = {hello_server, {hello_server, start_link, []},
Restart, Shutdown, Type, [hello_server]},
{ok, {SupFlags, [AChild]}}.
src/hello_app.erl
-module(hello_app).
-behaviour(application).
%% Application callbacks
-export([start/2, stop/1]).
%% ===================================================================
%% Application callbacks
%% ===================================================================
start(_StartType, _StartArgs) ->
hello_sup:start_link().
stop(_State) ->
ok.
ebin/hello.app
{application,hello,
[{description,[]},
{vsn,"1"},
{registered,[]},
{applications,[kernel,stdlib]},
{mod,{hello_app,[]}},
{env,[]},
{modules,[hello_app,hello_server,hello_sup]}]}.
运行代码:
erl -pa ebin
1> application:start(hello). ok 2> whereis(hello_sup). <0.37.0> 3> whereis(hello_server). <0.38.0> 4> hello_server:say_hello(). Hello ok 5> application:stop(hello). =INFO REPORT==== 17-Dec-2012::15:37:47 === application: hello exited: stopped type: temporary ok 6> whereis(hello_sup). undefined 7> whereis(hello_server). undefined