启动erl,然后m(gen_server),可以查看gen_server的export函数。
gen_server基于gen模块实现。
是一个典型的client -server模式。
偷张图 - ^_^:
如何启动?
gen_server:start_link
gen_server:start
.....
启动main proc后,进入初始化函数init,返回{ok,State},此State即是gen_server初始状态。
至此,启动完毕
....
gen_server中callback实现==>
同步:
handle_call(alloc, _From,State) -> {reply, Ch, State}.
异步:
handle_cast({free, Ch}, State) ->, {noreply, State}.
其他:
handle_info({'EXIT', Pid, Reason}, State) -> {noreply, State1}.如何请求gen_server?同步=》gen_server:call && gen:call(xxx,'$gen_call'..异步=》gen_server:cast && gen:call(...'$gen_cast'...其他:Pid ! Msg && erlang:send..等等如何stop gen_server?a.如果处于监控树种,则无需做任何的处理,它的终结使命叫给了parent sup...b.如果是stand-alone的话,那就自己定制一个stop策略对于a,若是想在sup终结server的时候清除相应的mem&&data。。。等等之类的呢?那你可以在init中加入trap,然后对shutdown进行处理,detail如下:init(Args) -> ..., process_flag(trap_exit, true), ..., {ok, State}. ...terminate(shutdown, State) -> ..code for cleaning up here.. ok.至于b,则需要exprot一个fun。。... export([stop/0]). ... stop() -> gen_server:cast(ch3, stop). ... handle_cast(stop, State) -> {stop, normal, State}; handle_cast({free, Ch}, State) -> .... ... terminate(normal, State) -> ok.其实gen_server的内部实现很简单,想深入了解,那只能去read the fucking source code!!!不过可以重点看下call和cast的实现区别(简单看看):Cast =>do_cast(Dest, Request) -> do_send(Dest, cast_msg(Request)), ok.do_send(Dest, Msg) -> case catch erlang:send(Dest, Msg, [noconnect]) of noconnect -> spawn(erlang, send, [Dest,Msg]); Other -> Other end.call =>call(Process, Label, Request) -> call(Process, Label, Request, ?default_timeout).call(Name, Label, Request, Timeout) when is_atom(Name), Timeout =:= infinity; is_atom(Name), is_integer(Timeout), Timeout >= 0 -> case whereis(Name) of Pid when is_pid(Pid) -> do_call(Pid, Label, Request, Timeout); undefined -> exit(noproc) end;其中do_call有点长,不过重点不长。。。catch erlang:send(Process, {Label, {self(), Mref}, Request}, [noconnect]),
receive {Mref, Reply} ->
....after Timeout ->...当然两者区别多着去了,说这里只不过是,说明下erlang的一种异步&&同步的实现本质差异。