gen_server:call与直接调用一个函数

时间:2018-07-04 13:09:32

标签: erlang

让我们说gen_server中有两个进程正在运行(由主管启动)。一个像这样调用另一个函数:brother:function(Param)。它也可以做gen_server:call(brother, Param)。每种情况都有哪些用例?在这两种情况下,第一个进程都等待brother中的函数完成,因此我不知道何时应使用每个函数。

2 个答案:

答案 0 :(得分:3)

直接没有任何区别。但是,直接使用gen_server:call(或cast)意味着您将 other 模块绑定到gen_server的内部。试想一下,以后您想更改brother的注册,以便它使用其他内容(例如,外部库,例如gproc)。现在,您必须去查找使用gen_server:call(brother, ...)的每个位置并进行修复,重复很多代码以获取服务器名称,依此类推。总体来说,拥有brother:function(...)

要容易得多

这同样适用于更改调用或强制转换的内部结构。仅将所有内容作为参数传递给函数,然后使用该函数构造参数变得容易得多。例如,假设您使用该函数创建模块内部的记录。

因此,总体而言,这主要是关注点的封装和分离。通常,该模块应注意查找将呼叫发送到的正确服务器以及呼叫的正确格式。

答案 1 :(得分:2)

  

第一个过程等待兄弟中的功能完成

不,不是。或者更确切地说,这取决于如何定义function。经常是这样

function(Param) -> gen_server:call(?MODULE, {function, Param}) 
%% or gen_server:call(?MODULE, Param) if there's only one kind of request

,实际的实现将在brother:handle_call中。

很明显,在这种情况下,调用brother:function(Param)或手动执行gen_server:call的结果没有区别,但是调用brother:function是更好的做法:它可以隐藏调用模块具有的详细信息没有业务知道,并允许brother进行更改。