`
litaocheng
  • 浏览: 333760 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

gen_server牛角尖问答

阅读更多
我们以Module代表gen_server的callback模块
1, 实现gen_server behaviour的模块会产生一个新的process么?
毫无疑问,太会了!通过调用proc_lib:start_link/5创建process

2, gen_server:start_link/3,4中的Options参数有什么用处?
Options中只有这几个选项:{debug,Dbgs} | {timeout,Time} | {spawn_opt,SOpts},
debug是用来和sys模块相关联的;咱们通过proc_lib:start_link/5创建process的时候,如果初始化等待的时间超过了 Time,那么我们的gen_server:start_link会返回{error, timeout}的错误;spawn_opt是给spawn_opt传递的参数。

3, Module:init/1的那些返回值都什么意思?
{ok, State},就不用说了,一切正常,State将为gen_server的State;
{ok, State, Timeout},也很正常,只是如果process在Timeout(>=0,ms)时间内没有收到任何消息,那么将产生一个timeout消息,这个消息要在handle_info中处理哦。
{ok, State, hibernate}, 还是正常,只是我们在process启动后,就让它先”睡眠“,因为我们知道最近一段时间内,我们还不用这个process,此process睡眠的好处就是可以最大限度的减少其内存占用,当有消息到达时,process就会”惊醒“,重新工作。
{stop, Reason},oops,出错了,process将会调用exit(Reason)退出。如果init没有预期,我们就退出吧。
ingore,既然要求忽略了,什么都不做,退出吧。

4, gen_server:multi_call/2,3,4这几个哥们是干嘛用的?
multi就是多的意思嘛,mulit_call肯定就是进行多个调用请求哦。
先说他们的关系:
gen_server:multi_call(Name, Request)
= gen_server:multi_call([node() | nodes()], Name, Request)
= gen_server:multi_call([node() | nodes()], Name, Request, infinity)
称他们为兄弟,我看称他们为三胞胎还不错。
想多个node请求本地名为Name的gen_server behaviour, 然后收集结果,返回。
其返回值格式为:{Replies,BadNodes},其中Replies为[{Node, Reply}],BadNodes,不用说就是那些没有正常返回应答的节点了。
mulit_call/4最后一个Time参数指定的是每个Reply等待的超时时间。

5, gen_server:reply/2有嘛用处?
如果在Module:handle_call/3中,我们不能返回结果,我们可以保存handle_call中的From参数,在结果生成的时候,返回给Caller。

6, Module:handle_call/3 返回{noreply,NewState}会怎样?
怎样?明明是handle_call处理的是同步的请求,处理完了就应该告诉Caller,是死是活,是成功是失败,可是你noreply,
Caller只能傻傻的等待了。等多久?默认的是5秒,gen_server:call/3就调用exit({timeout, Description}),退出了。。

7, 我用gen_server竟然死锁了?
天呀,在erlang中怎么遇到锁了?肯定是你使用不当!
name() ->
	gen_server:call(?SERVER, name).
address() ->
	gen_server:call(?SERVER, address).

all_info() ->
	gen_server:call(?SERVER, all_info).

.....
handle_call(all_info, _From, State) ->
	Name = name(),
	Address = address(),
	{reply, {Name, Address}, State};

这么写,活该你死锁。
handle_call是同步调用,你在内部又调用name(), address(),能不锁么?
要求就是:不要在handle_call/3内部调用另一个gen_server:call相关的函数。

时间关系,gen_server先钻到这里。
分享到:
评论
1 楼 GodwitNow 2009-04-15  
哈哈~
以前我在使用gen_server的时候就在handle_call里面调用另外一个handle_call了~
受教!

相关推荐

Global site tag (gtag.js) - Google Analytics