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的简单应用的更多相关文章

  1. erlang OTP gen_server 图解分析

    http://www.hoterran.info/otp-gen_server-sourcecode 在阅读erlang的otp源码gen_server.erl的时候,一直想写点什么,用一种最好的方式 ...

  2. OTP gen_server

    erlang behaviour小结之gen_server OTP入门 分类: Erlang2012-08-06 18:55 867人阅读 评论(0) 收藏 举报 servererlangcallba ...

  3. 使用Erlang和Yaws开发REST式的服务

    看过那张很出名的“Apache vs. Yaws”图么?是不是在考虑你也应该使用Yaws了?这些图给人的第一印象是,Yaws在可伸缩性上具有难以置信的巨大优势,它可以扩展到80000个并行的连接,而 ...

  4. Mochiweb的设计分析

    http://blog.csdn.net/dp0304/article/details/6994435 Web服务器的基本工作大致分3步: 接收HTTP请求: 处理HTTP请求,生成响应内容: 发送响 ...

  5. Erlang OTP编程初体验——gen_server和行为模式

    http://blog.sina.com.cn/s/blog_3fe961ae0101k4p6.html 行为模式其实非常类似于面向对象语言中的接口,至少笔者是这么理解的.OTP行为模式将一些反复出现 ...

  6. Erlang 104 OTP

    笔记系列 Erlang环境和顺序编程Erlang并发编程Erlang分布式编程YawsErlang/OTP 日期              变更说明 2014-12-21 A Outline, 1 A ...

  7. Erlang/OTP设计原则(文档翻译)

    http://erlang.org/doc/design_principles/des_princ.html 图和代码皆源自以上链接中Erlang官方文档,翻译时的版本为20.1. 这个设计原则,其实 ...

  8. Erlang cowboy 处理简单的HTTP请求

    Erlang cowboy 处理简单的HTTP请求 原文出自: Handling plain HTTP requests 处理请求的最简单的方式是写一个简单的HTTP处理器.它的模型参照Erlang/ ...

  9. Erlang/OTP:基于Behaviour的回调函数

    原始链接:https://blog.zhustec.me/posts/erlang-otp-1-callback-based-on-behaviour OTP 是什么 OTP 的全称是开源电信平台 ( ...

  10. Erlang generic standard behaviours -- gen_server hibernate

    hibernate 主要用于在内存空闲时,通过整理进程的stack,回收进程的heap 来达到回收内存节省资源的效果. hibernate 可用于OTP 进程以及普通进程, hibernate 的官方 ...

随机推荐

  1. Openfoam UPstream类探索

    前言 上篇文章我们大体捋顺了Pstream类,但上篇没有讲到的是Pstream类很多东西是从UPstream类继承来的 这次我们大体看一下UPstream类,以避免Pstream类内很多继承来的东西不 ...

  2. VueJs 监听 window.resize 方法---窗口变化

    mounted() { let _this = this; window.onresize = ()=>{ return (()=>{ this.vscreen.height=docume ...

  3. NOIP2017 - D2T3 - phalanx

    按照思维难度加大和代码难度减小的顺序,我们来看这道题的不同做法. 若你无畏,我亦无畏 - 平衡树 平衡树简直是天然用来维护这种操作的--合并两个区间,提取一个值.我们可以对每个行的前 \(m-1\) ...

  4. 基于Python的OpenGL 02 之着色器

    1. 概述 本文基于Python语言,描述OpenGL的着色器 环境搭建以及绘制流程可参考: 基于Python的OpenGL 01 之Hello Triangle - 当时明月在曾照彩云归 - 博客园 ...

  5. JAVA快速获取网络图片或者URL图片并保存到本地

    JAVA快速获取网络图片或者URL图片并保存到本地,直接上代码: package com.xh.service;import org.springframework.stereotype.Servic ...

  6. ModuleNotFoundError: No module named 'flask._compat'

    出现 "ModuleNotFoundError: No module named 'flask._compat'" 提示的解决办法: 参考 https://zhuanlan.zhi ...

  7. vue学习笔记:vue.js基础语法

    一.VUE 概述 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用.Vue 的核心库只关注视图层,不仅 ...

  8. wandb: Network error (ConnectionError), entering retry loop.

    超算使用wandb总是连接超时,设置为offline模式即可 import os import wandb os.environ["WANDB_API_KEY"] = 'KEY' ...

  9. cuda+pytorch环境安装

    本机cuda版本为v11.5 conda install cudatoolkit 使用 CUDA 11.3版本的配置 conda install pytorch==1.11.0 torchvision ...

  10. ant design vue datePicker 日期时间范围设置默认为当天0点-23点59

    <template> <a-card :bordered="false"> <a-range-picker show-time :default-va ...