Chinaunix首页 | 论坛 | 博客
  • 博客访问: 150103
  • 博文数量: 92
  • 博客积分: 2035
  • 博客等级: 大尉
  • 技术积分: 874
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-10 09:03
文章分类

全部博文(92)

文章存档

2010年(38)

2009年(54)

我的朋友

分类:

2009-11-28 21:28:55

gen_server的源代码在C:\Program Files\erl5.7.3\lib\stdlib-1.16.3\src\gen_server.erl

The relationship between the behaviour functions and the callback functions can be illustrated as follows:行为函数和回调函数的关系

gen_server module            Callback module
----------------- ---------------
gen_server:start_link -----> Module:init/1

gen_server:call
gen_server:multi_call -----> Module:handle_call/3

gen_server:cast
gen_server:abcast -----> Module:handle_cast/2

- -----> Module:handle_info/2

- -----> Module:terminate/2

- -----> Module:code_change/3
%%% The work flow (of the server) can be described as follows:
%%%
%%%   User module                          Generic
%%%   -----------                          -------
%%%     start            ----->             start
%%%     init             <-----              .
%%%
%%%                                         loop
%%%     handle_call      <-----              .
%%%                      ----->             reply
%%%
%%%     handle_cast      <-----              .
%%%
%%%     handle_info      <-----              .
%%%
%%%     terminate        <-----              .
%%%
%%%                      ----->             reply
%%%
%%%
%%% ---------------------------------------------------






gen_fsm module                    Callback module
-------------- ---------------
gen_fsm:start_link -----> Module:init/1

gen_fsm:send_event -----> Module:StateName/2

gen_fsm:send_all_state_event -----> Module:handle_event/3

gen_fsm:sync_send_event -----> Module:StateName/3

gen_fsm:sync_send_all_state_event -----> Module:handle_sync_event/4

- -----> Module:handle_info/3

- -----> Module:terminate/3

- -----> Module:code_change/4
%%% The work flow (of the fsm) can be described as follows:
%%%
%%%   User module                           fsm
%%%   -----------                          -------
%%%     start              ----->             start
%%%     init               <-----              .
%%%
%%%                                           loop
%%%     StateName          <-----              .
%%%
%%%     handle_event       <-----              .
%%%
%%%     handle__sunc_event <-----              .
%%%
%%%     handle_info        <-----              .
%%%
%%%     terminate          <-----              .
%%%
%%%
%%% ---------------------------------------------------



gen_event module                   Callback module
--------------- -------------
gen_event:start_link -----> -

gen_event:add_handler
gen_event:add_sup_handler -----> Module:init/1

gen_event:notify
gen_event:sync_notify -----> Module:handle_event/2

gen_event:call -----> Module:handle_call/2

- -----> Module:handle_info/2

gen_event:delete_handler -----> Module:terminate/2

gen_event:swap_handler
gen_event:swap_sup_handler -----> Module1:terminate/2
Module2:init/1

gen_event:which_handlers -----> -

gen_event:stop -----> Module:terminate/2

- -----> Module:code_change/3




-module(server4).
-export([start/2,rpc/2, swap_code/2]).

start(Name, Mod) ->register(Name, spawn(fun() -> loop(Name, Mod, Mod:init()) end)).

swap_code(Name, Mod) ->rpc(Name, {swap_code, NewMod}).

rpc(Name, Request) ->
    Name ! {self(), Request},
    receive
        {Name, crash} ->exit(rpc);
        {Name, ok, Response} ->Response
    end.
    
loop(Name, Mod, State) ->
    receive
        {From, {swap_code,NewCallbackMod}} ->
            From!{Name,ok,ack},
            loop(Name, NewCallbackMod, OldState);
        {From, Request} ->
            try Mod:handle(Request, OldState) of
                {Response, NewState} ->
                    From ! {Name,ok, Response},
                    loop(Name, Mod, NewState)
            catch
                _:Why ->
                    log_the_error(Name, Request, Why),
                    From ! {Name, crash},
                    loop(Name, Mod, OldState)
            end
    end.
   
log_the_error(Name, Request, Why) ->
    io:format("Server ~p request ~p~n"
              "caused exception ~p~n",[Name, Request,Why]).



------------------------------------------------------------------------

-module(name_server1).
-export([init/0, add/2, whereis/1, handle/2]).
-import(server3, [rpc/2]).

%%client routines
add(Name, Place) -> rpc(name_server, {add, Name, Place}).
whereis(Name)    -> rpc(name_server, {whereis, Name}).

%%callback routines
init() -> dict:new().

handle({add,Name, Place}, Dict) ->{ok, dict:store(Name, Place, Dict)};
handle({whereis, Name}, Dict) ->{dict:find(Name, Dict), Dict}.

---------------------------------------------------------------------------

1>server3:start(name_server, name_server1).
2>name_server:add(joe, "at home").
3>name_server:whereis(joe).

---------------------------------------------------------------------------
gen_server:start_link(,Mod,,) 会回调Mod:init().

%



-module(my_bank).
-behaviour(gen_server).
-export([start/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-compile(export_all).

start() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
stop()  -> gen_server:call(?MODULE, stop).

new_account(Who)         -> gen_server:call(?MODULE, {new, Who}).
deposit(Who, Amount)     -> gen_server:call(?MODULE, {add, Who, Amount}).
withdraw(Who, Amount)    -> gen_server:call(?MODULE, {remove, Who, Amount}).

init([])  ->{ok, ets:new(?MODULE, [])}.

handle_call({new, Who}, _From, Tab) ->
    Reply = case ets:lookup(Tab, Who) of
                []  -> ets:insert(Tab, {Who, 0}),
                       {welcome, Who};
                [_] -> {Who, you_already_are_a_customer}
            end,
    {reply, Reply, Tab};
handle_call({add, Who, X}, _From, Tab) ->
    Reply = case ets:lookup(Tab, Who) of
                [] -> not_a_customer;
                [{Who, Balance}] ->
                    NewBalance = Balance + X,
                    ets:insert(Tab, {Who, NewBalance}),
                    {thanks, Who, your_balance_is, NewBalance}
            end,
    {reply, Reply, Tab};
handle_call({remove,Who,X}, _From, Tab) ->
    Reply = case ets:lookup(Tab, Who) of
                [] -> not_a_customer;
                [{Who,Balance}] when X =< Balance ->
                    NewBalance = Balance -X,
                    ets:insert(Tab, {Who, NewBalance}),
                    {thanks, Who, you_balance_is, NewBalance};
                [{Who, Balance}] ->
                    {sorry, Who, you_only_have, Balance, in_the_bank}
            end,
    {reply, Reply, Tab};
handle_call(stop, _From, Tab) ->
    {stop, normal, stopped, Tab}.
   
handle_cast(_Msg, State) -> {noreply, State}.
handle_info(_Info, State) -> {noreply, State}.
terminate(_Reason, _State) -> ok.
code_change(_OldVsn, State, Extra) ->{ok, State}.
阅读(283) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~