OTP: gen_server的简单应用
1、确定回调模块名
2、编写接口函数
3、在回调模块里编写六个必需的回调函数
1、确定回调模块名
my_bank
2、编写接口方法
start() 打开银行
stop() 关闭银行
new_account(Who) 创建一个新账户
deposit(Who,Amount) 把钱存入银行
withdraw(Who,Amount) 把钱取出来(如果有结余的话)。
gen_server:start_link({local,Name},Mod,…) 会启动一个本地服务器。如果第一个参数是原子global,它就会启动一个能被Erlang节点集群访问的全局服务器。start_link的第二参数是Mod,也就是回调模块名。宏?MODULE会展开成模块名my_bank。
gen_server:call(?MODULE,Term)被用来对服务器进行远程过程调用。
3、编写回调方法
回调模块必需导出六个回调方法:
init/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2,code_change/3.
其中的handle_call/3函数最为最重要
这个模块包含了一套简单的框架,可以填充它们来制作服务器。如果忘记定义合适的回调函数,编译器就会根据关键字-behaviour来生成警告或错误消息。start_link()函数里的服务器名(宏?SERVER)需要进行定义,因为它默认是没有定义的。
这段代码中的Reply会作为远程过程调用的返回值发挥客户端。
State 只是一个代表服务器全局状态的变量,它会在服务器里到处传递。在上面的银行模块中,这个状态不会发生变化,只是一个ETS表的索引,属于常量。
启动服务器
gen_server:start_link(Name,Mod,InitArgs,Otps) 这个调用是所有事务的起点。
它会创建一个名为Name的通用服务器,回调模块是Mod,Otps则控制通用服务器的行为。在这里可以指定消息记录、函数调试和其他行为。通用服务器通过调用Mod:init(InitArgs)启动。
初始化服务器
init(Args) -> {ok,State}|
{ok,State,Timeout}|
ignore|
{stop,Reson}
init([]) ->
{ok,#state{}}.
如果返回{ok,State},就说明我们成功启动了服务器,初始状态是State。
调用服务器
要调用服务器,客户端程序需要执行gen_server:call(Name,Request).他最终调用的回调模块里的handle_call/3.
handle_call(Request,From,State) ->
{reply,Reply,State}|
{reply,Reply,State,Timeout}|
{noreply,State}|
{noreply,State,Timeout}|
{stop,Reason,Reply,State}|
{stop,Reason,State}
Request(gen_server:call/2的第二个参数)作为handle_call/3的第一个参数重新出现。From是发送请求的客户端进程PID,State则是客户端的当前状态。
通常会返回{reply,Reply,NewState},Reply会返回客户端,成为gen_server:call的返回值。NewState则是服务器接下来的状态。
noreply会让服务器继续工作,但客户端会等待一个回复,所以服务器必需把回复的任务委派给其他进程。用适当的stop会停止服务器。
gen_server:call和handle_call之间的交互,作用是实现远程过程调用。
调用和播发
gen_server:cast(Name,Msg)则实现了一个播发(cast),也就是没有返回值得调用(实际上就是一个消息,但习惯上称它为播发来与远程过程调用相区分)。
handle_cast(Msg,State) ->
{noreply,State}|
{noreply,State,Timeout}|
{stop,Reason,State}
发给服务器的自发性消息
回调函数handle_info(Info,State)被用来处理发给服务器的自发性消息。
自发性消息是一切未经显示调用gen_server:call或gen_server:cast而到达服务器的消息。
例如:如果服务器连接到另一个进程并捕捉推出信号,就可能会突然收到一个预料之外的{‘EXIT’,Pid,What}消息。除此之外,系统里任何知道通用服务器PID的进程都可以向它发送消息。这样的消息在服务器里表现为info值。
handle_info(_Info,State) ->
{noreply,State}|
{noreply,State,Timeout}|
{stop,Reason,State}
后会有期,宝贝
服务器会因为许多原因而终止。某个以handle_开头的函数也许会返回一个{stop,Resason,NewState},服务器也可能崩溃并生成{‘EXIT',reason}。在所有这些情况下,无论他们是怎样发生的,都会调用terminate(Reason,NewState)。模板如下:
这个函数是在某个gen_server即将终止时调用的。
它应当是Module:init/1的逆操作,并进行必要的清理。
当他返回时,<mod>gen_server</mod>终止并生成原因Reason。
terminate(Reason,State) -> void().
这段代码不能返回一个新状态,因为已经终止。
但是了解服务器的终止状态非常有用。可以把状态保存到磁盘,把它放入消息发送给别的进程,或者根据应用程序的意愿丢弃它。如果想让服务期过后重启,就必须编写重启函数,由terminate/2触发。
代码更改
在服务器运行时更改它的状态。这个回调函数会在系统执行软件升级时由版本处理子系统调用。
在代码更改时转换进程状态
code_change(OldVsn,State,Extra) -> {ok,NewState}
参考引用:
Erlang程序设计(第二版)
OTP: gen_server的简单应用的更多相关文章
- erlang OTP gen_server 图解分析
http://www.hoterran.info/otp-gen_server-sourcecode 在阅读erlang的otp源码gen_server.erl的时候,一直想写点什么,用一种最好的方式 ...
- OTP gen_server
erlang behaviour小结之gen_server OTP入门 分类: Erlang2012-08-06 18:55 867人阅读 评论(0) 收藏 举报 servererlangcallba ...
- 使用Erlang和Yaws开发REST式的服务
看过那张很出名的“Apache vs. Yaws”图么?是不是在考虑你也应该使用Yaws了?这些图给人的第一印象是,Yaws在可伸缩性上具有难以置信的巨大优势,它可以扩展到80000个并行的连接,而 ...
- Mochiweb的设计分析
http://blog.csdn.net/dp0304/article/details/6994435 Web服务器的基本工作大致分3步: 接收HTTP请求: 处理HTTP请求,生成响应内容: 发送响 ...
- Erlang OTP编程初体验——gen_server和行为模式
http://blog.sina.com.cn/s/blog_3fe961ae0101k4p6.html 行为模式其实非常类似于面向对象语言中的接口,至少笔者是这么理解的.OTP行为模式将一些反复出现 ...
- Erlang 104 OTP
笔记系列 Erlang环境和顺序编程Erlang并发编程Erlang分布式编程YawsErlang/OTP 日期 变更说明 2014-12-21 A Outline, 1 A ...
- Erlang/OTP设计原则(文档翻译)
http://erlang.org/doc/design_principles/des_princ.html 图和代码皆源自以上链接中Erlang官方文档,翻译时的版本为20.1. 这个设计原则,其实 ...
- Erlang cowboy 处理简单的HTTP请求
Erlang cowboy 处理简单的HTTP请求 原文出自: Handling plain HTTP requests 处理请求的最简单的方式是写一个简单的HTTP处理器.它的模型参照Erlang/ ...
- Erlang/OTP:基于Behaviour的回调函数
原始链接:https://blog.zhustec.me/posts/erlang-otp-1-callback-based-on-behaviour OTP 是什么 OTP 的全称是开源电信平台 ( ...
- Erlang generic standard behaviours -- gen_server hibernate
hibernate 主要用于在内存空闲时,通过整理进程的stack,回收进程的heap 来达到回收内存节省资源的效果. hibernate 可用于OTP 进程以及普通进程, hibernate 的官方 ...
随机推荐
- JVM相关知识学习
JVM的垃圾回收算法是什么? 分代回收算法:然后详细阐述年轻代有哪些算法,老年代有哪些算法 垃圾收集器总结: 最初使用的是Serial + Serial Old收集垃圾,最简单,因为二者都是单线程的, ...
- 关于 Knex update 语句报错:Undefined binding(s) detected when compiling UPDATE
下图是详细的报错截图,我敢保证前端传递的数据一个不漏,但还是报我没有绑定对应的字段: 官方文档的使用案例基本上都是where 子句在 update 语句之前.但,select 语句的 where 子句 ...
- 02#Web 实战:实现树形控件
前言 这是一篇个人练习 Web 前端各种常见的控件.组件的实战系列文章.本篇文章将介绍个人通过 JQuery + 无序列表 + CSS 动画完成一个简易的树形控件. 最终实现的效果是: 这样结构比较复 ...
- 如何创建一个浏览器版的`Window11`
如何创建一个浏览器版的Window11 我们接下来将创建一个在浏览器运行的Window11,可以先看看效果图 这是基于Windows 11 in React修改的功能,我们接下来就将使用Windows ...
- Reverse for 'blog_detail.html' not found.解决方法
初学django遇到了以下问题: 查找解决方法的时候发现有以下几个原因: 1.字母打错 2.多加了空格 随后 我发现 报错的代码中多加了'.html'..删掉后就没问题了.
- vue - 环境变量和模式
1.在项目根目录中创建.env 或者 .env.xxx 的文件来指定环境变量 .env # 在所有的环境中被载入 .env.local # 在所有的环境中被载入,但会被 git 忽略 .env.[mo ...
- .NET6+WebApi+Vue 前后端分离后台管理系统(二)
项目搭建: 这个项目使用的开发工具是:VSCode,工具的下载和安装这里就不赘述了,自行百度吧.使用的技术主要是: Vue3.Element Plus 等,Vue 项目的搭建这里也不赘述,如果不熟悉可 ...
- C++数据结构-结构体
C++数据结构-结构体 学生信息 http://oj.61coding.cn/problem.php?cid=1028&pid=0 #include<bits/stdc++.h> ...
- Day12 面向对象
面向对象 前提须知:Java中想要创建对象,必须要有类的存在 类和对象的关系: 依赖关系:需要根据类,创建对象 数量关系:根据一个类,可以创建出多个对象 创建Student类的对象进行使用 创建对象的 ...
- sping入门介绍-bean标签的属性
bean标签的属性 1 .基础属性 <bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl" ...