gen_server,是erlang中很重要的一个行为框架,他主要的职责就是什么呢,书上说的很多,不过说到底,他就是负责创建成和进程之间的通信!其实看了application和supervious等行为框架,你会发现,我们在进行erlang开发的时候大多时候用的都是erlang的固定行为框架,这应该成为了一种默认的模式,一般情况下,我们都是按照这种方式来开发的,我看过好多的erlang代码,包括复杂以及简单的otp开发代码,都是以这种方式在写码!!!
-module(monster_manager). -behaviour(gen_server). -record(state, {seq = 1}). -export([start_link/0]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). start_link()-> gen_server:start_link({local, ?MODULE}, ?MODULE , [], []). %%启动一个进程,在作为监督树上的一个进程 init([]) -> {ok, #state{}}. %%初始化进程的状态 %% %% handle_call %% handle_call(_Request, _From, State) -> Reply = ok, {reply, Reply, State}. %%同步调用方法,这里很容易看到函数的返回值里不仅有状态还有,一个reply的值 %% %% handle_cast %% handle_cast(_Msg, State) -> {noreply, State}. %%异步调用方法无返回值但是有状态 %% %% handle_info %% %% handle_info({stop_monster,ProcName}, State) -> monster_sup:stop_monster(ProcName), {noreply, State}; handle_info({stop_iobject,ProcName}, State) -> monster_sup:stop_iobject(ProcName), {noreply, State}; handle_info(_Info, State) -> {noreply, State}. %%终止进程 terminate(_Reason, _State) -> ok. %%代码热更部分 code_change(_OldVsn, State, _Extra) -> {ok, State}.
以上是一个我们产生怪物的使用gen_server的小框架(部分代码),可以看到这里有gen_server必备的几个方法,这些是必备的方法,否则会报错!
我们什么时候使用handle_info呢?既不是同步也不是异步消息的方式我们都用它去匹配!这里如果仅仅是写一些自己的小程序,估计是用不到handle_info的,不过当我们是用消息模式来通信,例如,Message!Pid的时候我们都是用它来匹配,但是最好别这样做,erlang的编程有些时候比较机械规范,好像我认识的人和我看过的代码,大都以一种方式在写!
来说说init(),这个方法,我们其实也是基本用不到的,原因很简单,我们在前面的sup中已经初始化了他的每一个子进程,不过如果因为一些特殊的原因,这个进程需要自己一些独特的状态是,我们才会在这里来初始化。 以上就是gen_server的简单讲解,这里gen_server和gen_fsm会有许多人搞混,虽然他们的解释很不一样,但是如果是第一次用erlang没准还真的就会不知道什么时候该用哪个,我就是这样,一开始的时候单纯的认为,gen_fsm(明天说一下)既然能解决为什么要用gen_server,那个时候就是每天都在思考他们为什么一定要这么用,说实话,有点钻牛角尖,因为我们是上层应用者,只要知道在什么环境下用哪一个更好就可以了,对于下一层的东西如果感兴趣有时间可以看一看,不过我不是专门搞研究的,所以并没有更深入的去研究。