erlang behaviour小结之gen_s erver

问题描述

首先清楚gen_s erver提供C/S架构中的服务端的实现,即定义了自己一套规范的服务器框架。drawapp8-cantk-27da905.part2.rar在以上基础上,具体学习下gen_s erver的实现过程。先是定义模块的行为模式为gen_s erver -module(lqg). -behaviour(gen_**). . 这里既然用了gen_s erver框架,那必须要实现gen_**的方法:gen_** callbacks-export(). 外加模块的对外调用函数:API-export(). -export(). 接下来就是实现上面定义的函数:start_link() -> gen_**:start_link({local, lqg}, lqg, [], []). 对于start_link,第一个参数为创建一个名为Name的**,现在的情况为在gen_srever将在本地被注册为lqg第二个参数lqg, 则是回调模块的名字,也就是回调函数所放的那个模块。在这里,接口函数( start_link)和回调函数(init, handle_call 和 handle_cast)。一般来说这是好的编程实践,将代表同一个进程的代码包含在同一个模块中。第三个参数[], 这个值将被原封不动传递给回调函数init。在这里,init无须任何输入数据将忽略这个参数.第四个参数[],是参数的列表。这里要注意的是:1.gen_**:start_link 是同步的。只有等到gen_**被完全初始化并准备接受请求之后才会返回2.如果gen_**是某棵**树的一部分,即gen_**是由一个督程启动的,那么必须使用gen_**:start_link 。还有另外一个函数 gen_**:start 用于启动一个**的gen_**,即不是某棵**树一部分的一个gen_**init(_Args) -> {ok, channels()}.在注册名称成功后,新的gen_**进程会调用回调函数lqg:init([])init返回{ok, State} ,其中State 是gen_**的内部状态。在这里,状态就是可用的频道channels。alloc() -> gen_**:call(lqg,alloc). 同步请求alloc() 用gen_**:call/2 实现.lqg 是gen_**的名字,必须和启动时的名字一样。alloc 是实际的请求此时,请求以消息的形式发送给这个gen_**。当收到了请求之后,gen_**调用handle_call(Request,From, State) ,它应返回一个元组 {reply, Reply, State1}。Reply是需要回馈给客户端的答复,同时State1 是gen_**的状态的新值。handle_call(_Request, _From, State) -> {Ch, State2} = alloc(State), {reply, Ch, State2}。 在这里,应答是分配了的频道Ch 然后gen_**将等待新的请求,并且现在保持了一个最新的可用频道的列表。handle_cast({free,Ch},Chs) -> Chs2 = free(Ch,Chs), {noreply, Chs2}. 在这里,新的状态便是更新过的可用频道列表Chs2 。gen_**现在又可以接受新的请求了。free(Ch) -> gen_**:cast(lqg,{free,Ch}).异步请求free(ch) 使用 gen_**:cast/2 实现lqg 是gen_**的名称。{free, Ch} 是实际的请求。请求被装在一个消息中发给gen_**的cast ,这调用了 free ,然后返回了 ok 。当gen_**收到请求之后,它会调用handle_cast(Request, Stats) ,会返回一个元组{noreply, State1} 。 State1 是gen_**状态的新值。handle_info(_Info, State) -> {noreply, State}. 用来处理请求之外的信息。terminate(_Reason, _State) -> ok. 终止函数,终止正在运行的进程若gen_**是某个**树的一部分,则无需停止函数。它的督程会自动终止它;如果gen_**并非某个**树的一部分,那么可以用一个停止函数;如果在终止之前需要进行一些清理工作,那么关闭策略必须是一个超时值,同时gen_**必须在init 函数中设置为捕获退出信号。当gen_**被要求关闭时,它就会调用回调函数terminate(shutdown, State)。code_change(_OldVsn, State, _Extra) -> {ok, State}.正如其名,此函数用来进行代码版本替换。是**热部署或代码升级时做callback修改进程状态_OldVsn:旧版本 State:gen_**的内部状态 _Extra:原封不动的传递过来的更新指令如果更新成功,返回{ok,State2},如果失败返回{error,Reason},并回**到旧版本。

时间: 2024-10-01 04:05:02

erlang behaviour小结之gen_s erver的相关文章

【转载】erlang 如何自定义 behaviour

什么是 behaviour ? 使用 erlang 编程的人都知道 OTP,而基于 OTP 框架创建进程的时候,常用的有四大 behaviour:  supervisor gen_server gen_fsm gen_event 那么什么是 behaviour?是做什么用的呢?        首先,写这篇文章之前我上谷歌查过人家对 behaviour 的定义,当然,是非官方定义,我一直没找着官方定义,如果有人有一个比较确切的定义,麻烦告诉我,大家共同学习嘛.       在 StackOverF

Erlang IO编程之文件目录操作常用方法小结_Erlang

Erlang用于操纵文件I/O的模块有: file模块:打开.读.写.关闭文件已经操作目录的方法基本都在这里 filename模块:提供平台独立方式用于操纵文件名 filelib模块:file模块的扩展,提供了更多的实用工具,在file模块基础上构建 io模块:一系列用于操作打开的文件的方法,解析格式.格式化输出等等. 1.打开文件: 复制代码 代码如下: {ok,F}=file:open("data1.dat",read). %读模式打开 {ok,F}=file:open("

Erlang中的基本元素操作小结_Erlang

Erlang shell中,用句号加空格.tab或回车来结束表达式,%表示注释的起点,;隔离子句.模块是.erl 文件,库的头文件.hrl, shell中的编译时c(),外编译命令时erlc, 退出shell用q(),或erlang:halt(). 变量以大写字母开头,且不能重新绑定变量,只能一次性赋值,具有不可变状态.原子是全局的,不需要宏定义或包含文件,以小写字母开头,还可放在单引号内,是极简表达式.   元组(tuple)是一些数量固定的项目归组成单一实体{,}, 由于是匿名的,通常在第一

erlang otp-erlang 服务器端编程 错误提示 variable 'State' is unbound

问题描述 erlang 服务器端编程 错误提示 variable 'State' is unbound -module(gen_server_template). %% gen_server_template -behaviour(gen_server). -export([start_link/0]). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/

Erlang虚拟机基础设施dtrace探测点介绍和使用

问题描述 最新的Erlang虚拟机(R15B01)很大的一个改进就是加入了对dtrace探测点的支持了, 具体参见这里, 主要目标是方便在生产实践中定位复杂的性能问题.目前Erlang的虚拟机的探测点支持Linux的**tap和freebsd的dtrace,我们刚好能够享受的到.作者Scott Lystig Fritchie在去年的euc中做了个很有意思的报告,参见这里,该PPT很详细的介绍了利用dtrace的探测点可以观察到erlang的行为如下: Processes: spawn, exit

Erlang初学:Erlang的一些特点和个人理解总结_Erlang

我对 Erlang 编程理念的理解:以分布式架构师的角度写代码. 函数式编程 Erlang 里面的函数是数学里面的函数:必须有返回值. 只要是函数必然有返回值,函数是一个过程,以英文的句号为函数结束符. 函数结束之前的表达式就是该函数的返回值. 所以这也是在 Erlang 里面的函数不会看到任何 return 语句的原因. C++ 等其他语言的函数和函数之前可以通过共享变量来实现消息传递. Erlang 里面的函数不可以,消息的传递通过函数的传入和传出. 也只是为什么 Erlang 号称天生之处

Linux环境下段错误的产生原因及调试方法小结_C 语言

最近在Linux环境下做C语言项目,由于是在一个原有项目基础之上进行二次开发,而且项目工程庞大复杂,出现了不少问题,其中遇到最多.花费时间最长的问题就是著名的"段错误"(Segmentation Fault).借此机会系统学习了一下,这里对Linux环境下的段错误做个小结,方便以后同类问题的排查与解决. 1. 段错误是什么 一句话来说,段错误是指访问的内存超出了系统给这个程序所设定的内存空间,例如访问了不存在的内存地址.访问了系统保护的内存地址.访问了只读的内存地址等等情况.这里贴一个

Erlang项目内存泄漏分析方法_Erlang

随着项目越来越依赖Erlang,碰到的问题也随之增加.前段时间线上系统碰到内存高消耗问题,记录一下troubleshooting的分析过程.线上系统用的是Erlang R16B02版本. 问题描述 有几台线上系统,运行一段时间,内存飙升.系统模型很简单,有网络连接,pool中找新的process进行处理.top命令观察,发现内存都被Erlang进程给吃完了,netstat命令查看网络连接数,才区区几K.问题应该是Erlang内存泄漏了. 分析方法 Erlang系统有个好处,可以直接进入线上系统,

Erlang中的Record详解_Erlang

在Erlang内部只有两种混合的数据类型:List和Tuple,而这两种都不支持命名访问,所以如果没有额外的库的话想创建像PHP.Ruby或Python中的关联数组(Ruby中的Hash)是不可能的 在Ruby中我可以这样做: 复制代码 代码如下: server_opts = {:port => 8080, :ip => '127.0.0.1', :max_connections => 10}  在Erlang的语法级别不支持这种表达 为了避免这种限制,Erlang虚拟机提供了一个伪数据