7

免责声明:作者是 OTP 的新手,对 Erlang 的语法、流程和消息有一些基本的了解。

我试图掌握 Erlang 中行为的概念,但我脑海中浮现出许多问题,使我无法理解像 gen_server 这样的行为的整个原理。

好的,gen_server 的官方文档显示了一个服务器和三个客户端连接的漂亮图表,用查询和回复箭头连接: http ://www.erlang.org/doc/design_principles/gen_server_concepts.html

但是每次我试图进一步理解这个概念时,我都会陷入困境。

有很多概念我无法在脑海中构建成一个更大的概念:

  • 行为实现;
  • 行为容器;
  • 行为界面;
  • 回调模块;
  • 回调函数;
  • API 函数。

我使用以下资源:

我仍然处于“我们在一个模块中调用一个函数,该函数调用另一个函数,该函数创建一个进程......卡住”的状态

有没有办法在图表中描述 gen_server 的概念?如何直观地显示客户端和服务器之间的交互流程?(帮助一个不太聪明的新手直观地理解这个概念)

例如像这里:http: //support.novell.com/techcenter/articles/img/dnd2003080506.gif

UPD:我尝试绘制自己的图表,但我仍然不明白图表中任何连接器的用途:http: //postimage.org/image/qe215ric/full/

UPD2:这与我希望看到的类似: http: //cryptoaarchy.org/wiki/Worker_patterns(模型)。但是,它没有显示模块、函数和进程之间的交互。

4

1 回答 1

12

我没有精确的图纸来解释它,但我有这一章和在展示如何构建 gen_server 之后的一章,从它背后的抽象原理开始。

为了帮助处理各个组件:

行为实现

行为本身有点像我之前链接的章节中显示的内容。它是一个具有一堆功能的模块,为您完成所有通用工作:接收消息、定义功能和隐藏的通信协议等。高级 OTP 内容包含用于进行软件升级的特殊类型的消息以及用于跟踪选项的特殊代码。

行为容器

我不确定这应该是什么。也许只是带有行为名称的模块?

行为接口

在您的行为实现所在的同一模块中,您必须定义一个behaviour_info/1函数。该函数将让 Erlang 编译器知道,其中包含的任何模块都需要一些回调-behaviour(SomeModuleName)SomeModuleName等效于包含实现和 behavior_info 函数的 (and )文件SomeModuleName.erl.beam

回调模块

该模块将包含所有特定代码,处理所有自定义内容。

回调函数

所有非通用的东西都以YourModule:SomeCall(Args). 这些由您的模块提供,其中包含该-behaviour(gen_server).行。

API函数

如果需要,回调模块有两个接口:一个用于gen_server行为(init/0、handle_call/3、handle_info/2、handle_cast/2、terminate/2、code_change/3),一个用于用户(start服务器,发送一些信息,要求返回一些信息)。

我可以试着这样描述

---------------------------------------------------------------------
| some process          |                server process             |
------------------------+--------------------------------------------
   [client]             |      [callback]     :        [behaviour]
                        |                     :
 callback:start >-------|---------------------:--> starting the process
                        |                     :           V
                        |                     :           |
                        |       init()  <-----:-----------`
                        |         |           :
                        |         `-----------:------> initial state
  {ok, Pid}  <----------|---------------------:----------,/
                        |                     :
 callback:store  >------|---------------------:--> handles message
 (calls the process)    |    (formats msg)    :           V
                        |                     :           |
                        |    handle_call() <--:-----------` 
                        |         |           :
                        |          `----------:--> updates state, sends reply
                        |                     :        V
                        |                     :        |
   gets result <--------|---------------------:--------`
                        |                     :       

所有通用部分都在服务器进程的右侧,在行为内,所有特定部分都在左侧(回调)。客户端使用回调模块的 API/接口联系服务器进程并对其产生影响。

您必须将行为视为某种非常通用的代码段,有时将其执行流程(对于更精确的部分,如接收和发送消息)放弃给特定代码(如何对这些消息作出反应)。

希望这会有所帮助。

于 2011-08-11T16:30:34.933 回答