意见箱
恒创运营部门将仔细参阅您的意见和建议,必要时将通过预留邮箱与您保持联络。感谢您的支持!
意见/建议
提交建议

erlang项目常见OTP行为模式

来源:恒创科技 编辑:恒创科技编辑部
2024-02-03 21:43:59


最近学习erlang有一些眉目了。在使用OTP进行erlang项目开发时,会遇到很多OTP的行为模式。而这种行为模式,有一些像面像对象中的设计模式。了解了这些东西,可以更好的使用OTP库进行erlang项目开发。起到了事半功倍的效果。下边是我最近学习的过程中见到的行为模式,我们从一个项目的创建开始。

一、项目目录创建


erlang项目常见OTP行为模式

项目创键时,首先是创建项目目录结构,打个比方,我们的项目说叫test.那么我们一般是建立一个文件件,起名为test,并在这个目录下边建立一些子目录,子目录和名字和作用如下:


doc:用来保存应用的说明文档


ebin:用来存储erlang编译之后的二进制文件,以及项目运行时的启始文件.app文件


include:用来存储保存全局记录或者元组的.hel文件,或者预定义头。


priv:用来存储与项目运行相关的其他文件,比如第三方语言写的库,或者像C++的动态库


src:所有的erl源码都会保存在这个文件夹下。


二、编辑项目启动元组数据


项目元组数据就是一般情况下,你所看到的ebin目录下的.app文件,我们用记事本打开这个.app文件就可以看到像下边这种结构的代码:


{application, test,

[{description, "RPC server for Erlang and OTP in action"},

"0.1.0"},

{modules, [test_app,

test_sup,

test_server]},

{registered, [test_sup, test_server]},

{applications, [kernel, stdlib]},

{mod, {test_app, []}}

]}.

通过代码我们可以看到三个数据,

第一个是application:

就是一个原子说明,说明元组数据是一个应用元组数据。

第二个是test:

很明显,这是我们的应用名称。

第三个是一个数组,我们可以看到数组中保存的所有数据都是以键值对的形式保存的。其中:

1.description,是说明部分。

2.vsn,这个是版本号,一般情况下,这里的版本号最好是按标准的主版本号,次版本号,分版本号来进行填写,因为有的时候,这个版本号会在代码热更新的时候用到。

3.modules,这里存的所有项目模块。

4.registered,注册进程,这个果注册到系统的单例模块进程名。

5.applications,应用启动之前要提前运行的OTP模块进程。

6.mod,应用启动时的模块,以及模块启动时所要代的参数。

三、模块建立

1.模块建立,自然是要先建立test_app.erl模块了,这个模块使用erlang的应用行为模式(application)。这个行为模式只有两个接口一个是启动应用的start,一个是关闭应用的stop.两个接口定义如下。

start(_StartType, _StartArgs) ->

test_sup:start_link().


_State) ->

ok.

可以看到,一个是start(_StartType,StartArgs),一个是stop(_State).一般情况下,start会在他的这个函数中调用你自已编写的监管者行为模式的start_link函数。而stop就只是简单的停止应用。

这里的StartType和StartArgs是应用启动时的两个要传给监督者进程的参数。

2.当我们的应用行为模式模块建好了之后,下一个自然就是用这个应用行为模式启动的应用根监管者行为模式模块test_sup了。监督者行为模式模块的主要任务就是管理其他子监督者模块和工作模块。一般定义模块时,除了监督者模块外其他的都是工作模块了,包括用户自已功能性模块也是工作模块。常见的工作行为模式就是gen_server行为模式,其他的我还没有学到。等学到了再来添加。

在监督者行为模式中,我们会看到下边的几个主要方法:

start_link() ->

?SERVER}, ?MODULE, []).


init([]) ->

Server

2000, worker, [tr_server]},

Children = [Server],

RestartStrategy = {one_for_one, 0, 1},

{ok, {RestartStrategy, Children}}.


比如这里的start_link()函数,这个函数其实就是通过OTP的supervisor模块来调用自已的init([])方法。而在这个调用的过程中,其实就把自已注册进了OTP的系统中了。同样的,OTP的其他行为模式,也基本上都是这种方式把自已的进程模块注册进OTP系统,由OTP系统来管理自已用行为模式创建的模块。


再说一下这里的init方法吧,这个方法里主要的一些参数格式是告诉OTP系统让OTP系统来管理你的进程,像这里的{one_for_one,0,1},前边的one_for_one,意思就是如果监督者有子进程错误退出,那么只启动这一个子进程,其他子进程不用启起。后边的0,1的意思是在1秒中退出的重起的最大次数为0,也就是子进程出错退出了,就不重起了。上边的Server中的无组中保存的数据是,监督者要起用的进程模块是那一个模块,模块是退出永远自动重启,还是永不重启,后边的2000意思是程序退出给的缓冲时间,这里可以设置成brutal_kill表示进程退出时马上退出。再后边的worker表示启动的进程为工作进程。最后边的数组是要启动的模块。


3.当然了,我们都有监督者模块了。怎么也得有一个让监督者模块来监督的东西吧。这里很自然的就走到了工作进程模块和子监督者进程模块。


总而言之,这样一直建立下去,一步一步的就把整个系统建立好了。



上一篇: MySQL 数据类型(转) 下一篇: 手机怎么远程登录云服务器?