介绍gen_server的示例代码

gen_server 和 gen_fsm 的区别和应用 在 Erlang 编程语言中,gen_server 和 gen_fsm 是两个重要的 OTP(Open Telecom Platform)设计模式,用于构建可扩展和可靠的并发应用程序。本文将详细介绍 gen_server 和 gen_fsm 的区别和应用,并提供相应的源代码示例。gen_server 适用于处理并发请求和维护内部状态的场景,而 gen_fsm 适用于实现有限状态机模型的场景。状态转换:gen_server 的状态转换是由客户端请求触发的,而 gen_fsm 的状态转换是由事件驱动的。 阅读详情

OTP(open telecomplatform),它的设计目标是用于做一套容错系统。最核心的概念就是behavior。类似类继承,在类里编写函数实现;而外层非应用逻辑相关的东西(热更新,监控机制等等)交OTP体系来控制。

先介绍gen_server模块。使用这个编写服务器只需要确认这3件事情:

1.      确定一个回调模块的名称;

2.      写接口函数;

3.      在回调模块中写需要的6个函数;

下面这个例子代码摘自《Erlang程序设计》16章。

代码: 

%%
%% Author:  erlang.hell
%% Date:    2012-11-18
%%

-module(my_bank).
-behavior(gen_server).
-export([start/0,stop/0,new_account/1,deposit/2,withdraw/2,
        init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).

%%====================================================================
%% server interface function
%%====================================================================
start()->
    gen_server:start_link({local,?MODULE}, ?MODULE,[],[]).

stop()->
    gen_server:call(?MODULE,stop).

new_account(Who)->
    gen_server:call(?MODULE,{new,Who}).

deposit(Who,Amount)->
    gen_server:call(?MODULE,{add,Who,Amount}).

withdraw(Who,Amount)->
    gen_server:call(?MODULE,{remove,Who,Amount}).

%%====================================================================
%% gen_server callbacks
%%====================================================================
init([]) ->
    Init=ets:new(?MODULE,[]),
    io:format("init ~p ~p",[Init,?MODULE]),
    {ok, Init}.

handle_call({new,Who}, _From, State) ->
    Reply = case ets:lookup(State,Who) of
        []->ets:insert(State,{Who,0}),
            {welcome,Who};
        [_]->{exsits,Who,you_already_are_a_customer}
    end,
    {reply, Reply, State}; 
handle_call({add,Who,Amount},_From,State)->
    Reply = case ets:lookup(State,Who) of
        []->not_a_customer;
        [{Who,Balance}]->
            NewBalance=Balance+Amount,
            ets:insert(State,{Who,NewBalance}),
            {thanks,Who,you_balance_is,NewBalance}
    end,
    {reply, Reply, State}; 
handle_call({remove,Who,Amount},_From,State)->
    Reply = case ets:lookup(State,Who) of
        []->not_a_customer;
        [{Who,Balance}] when Amount =< Balance ->
            NewBalance=Balance-Amount,
            ets:insert(State,{Who,NewBalance}),
            {thanks,Who,your_balance_is,NewBalance};
        [{Who,Balance}]->
            {sorry,Who,you_only_have,Balance,in_the_bank}
    end,
    {reply, Reply, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    io:format("is terminate.",[]),
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.


 

测试:

Eshell V5.9.1  (abort with ^G)

9>my_bank:new_account("erlang").

{welcome,"erlang"}

10>my_bank:deposit("erlang",10).

{thanks,"erlang",you_balance_is,10}

11>my_bank:deposit("erlang",20).

{thanks,"erlang",you_balance_is,30}

12> my_bank:withdraw("erlang",5).

{thanks,"erlang",your_balance_is,25}

 

遇到的麻烦:

4>my_bank:new_account("erlang",100).

** exception error: undefined functionmy_bank:new_account/2

5>my_bank:new_account("erlang").   

** exception exit:{noproc,{gen_server,call,[my_bank,{new,"erlang"}]}}

    in function  gen_server:call/2(gen_server.erl, line 180)

6>my_bank:deposit("erlang",10).

** exception exit:{noproc,{gen_server,call,[my_bank,{add,"erlang",10}]}}

    in function  gen_server:call/2(gen_server.erl, line 180)

在第4步的时候,我输入了2个参数,造成异常;后面即使输入正常了,但是这个gen_server已经没有工作;这种情况下就会爆出这样的错误。{noproc,{gen_server,call,…;遇到这个问题就需要再次调用my_bank:start()函数,将server启动起来。

 

掌握的知识点:

1.      OPT基本回调框架:

它存在6个回调函数函数,在模块起始的地方定义behavior自于gen_server;

State这个是贯穿于gen_server体系的回调函数;在每次回调都有权利修改他。Init函数用于生产出一个这样的tuple出来,handle函数用于加工;terminate的时候由于收场。

2.      基础语法:

函数覆盖的时候是使用“;”。如new,add,remove 3个方法是互为补充;我们就不能再每个函数后面写“.”。

使用cast语句来做条件分支:

cast ets:lookup( Table, Key ) of

[]->not_find;

[{ Who , Balance }] when Balance =< XXX ->

NewBalance=Balance-XXX,

ets:insert(Table,{Who,NewBalance},

{thinks};

[{Who,_}] ->

   {sorry,not_enough_money}.

3.      熟悉ets相关知识:

构建一个ets出来

ets:new(?MODULE,[]).

在ets中检索

ets:lookup(TBL,KEY).

插入ets中

ets:insert(TBL,{KEY,VAL}).

 

佛法无边。

数字IC设计随笔之二(VCS、DVE|Verdi单步调试) VCS+Verdi单步调试 阅读详情

相关推荐

从零到一:基于Matlab的二阶系统时域性能指标计算与可视化实战

本文提供了一份基于Matlab的二阶系统时域性能指标计算与可视化实战指南。通过详细的代码示例,手把手教你如何利用Matlab计算超调量、调节时间等关键指标,并绘制阶跃响应曲线进行可视化分析,帮助控制工程学习者和从业者快速掌握系统性能评估方法。

weixin_29096377的博客 268

[Erlang] - gen_server

gen_server.erl (上面的spawn经过fun的传来传去最后会来到gen_server)proc_lib.erl是一个关于进程的工具类,提供了同步启动进程的机制。

偶尔来看看 895

Spring AI实现RAG(检索增强生成)详解与实践

支持多种文件格式的文档加载实现高效的向量存储和检索构建智能的问答系统提供可追溯的知识服务RAG技术为AI应用提供了强大的知识增强能力,使得模型能够基于实际文档生成准确、可靠的回答。

beiduofen2011的专栏 1238

gen_server

文章目录gen_server1、gen_server起步1.1、第一步:确定回调模块的名称1.2、第二步:写接口函数1.3、第三步:编写回调函数2、gen_server回调的结构2.1、启动服务器时发生了什么2.2、调用服务器程序时发生了什么2.3、调用和通知2.4、发送给服务器的原生消息2.5、HastalaVista,Baby(服务器的终止)2.6、热代码替换3、gen_server详解3.1、启动服务器3.2、调用服务3.3、停止服务器3.4、代码更新 gen_server 1、gen_server起

rwxxtt的博客 867

【Docker】完美解决拉取镜像超时报错:ERROR: Get https://registry-1.docker.io/v2/

因为我们下载的镜像是外网的镜像资源,所以下载的速度会非常的慢,甚至大概率下载时会报错,所以需要我们配置一个国内的服务器镜像地址,国内服务器镜像地址有很多,这里咱们就说一下阿里镜像加速器的配置方法。

liu_chen_yang的博客 12万+

【网络教程】Ubuntu有线连接消失,无法联网怎么办!(亲测有效!)

文章目录问题描述解决方案 问题描述 今天打开Ubuntu,突然发现无法连接网络,并且打开设置,发现设置里面的网络已经没有了有线连接,只有VPN设置选项,如图 解决方案 按照下列的代码执行即可! # 关闭网路 service NetworkManager stop # 删除NetworkManager缓存文件 sudo rm /var/lib/NetworkManager/NetworkManager.state # 打开网络 service NetworkManager start 运行完

XiaoqiangClub的博客 1万+

Erlang运行时的错误

Erlang运行时发生错误时,会返回一些错误信息,理解这些信息,对于学好、用好Erlang来说是必要。 Erlang中的运行错误包括:badarg, badarith, badmatch, function_clause, case_clause, if_clause, undef, noproc, system_limit等。 badarg 这个错误很好理解,参数类型错误,传入函数的参...

weixin_30607029的博客 520

CARLA仿真:自定义地图与AI车辆行为编程

CARLA仿真:自定义地图与AI车辆行为编程 ,人工智能,计算机视觉,大模型,AI,本文围绕CARLA仿真平台,介绍了其基础功能与安装方法,详解地图系统,包括预设地图的加载切换及自定义地图的创建、导入与优化。还阐述了AI车辆的创建、属性设置、销毁,以及行为控制,如交通规则遵守、路径规划、复杂行为编程和行为树应用。同时涉及传感器与车辆感知、交通场景构建、自定义地图与AI行为结合应用、高级应用,以及常见问题解决方案和学习资源,为CARLA仿真应用提供全面指导。

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 11万+

angular学习006在angular6.0.8使用ng generate service创建服务报错

Argument type {providedIn: "root"} is not assignable to parameter type {providedIn: Type<any> | "root" | null}

lich_12345的博客 2022

SAP 公司间采购简介

SAP公司间采购(Intercompany Procurement)是指企业集团内部不同法人实体之间的采购和销售流程。这种流程在跨国公司或有多个独立运营子公司的企业中非常常见。SAP提供了标准的功能来处理公司间采购,确保财务和物流流程的透明性和效率。以下是SAP公司间采购的基本流程及其相关模块的简介。

我小时候很黑的博客 1376

【数据集】1970-2023年全球温室气体排放 GHG 数据集 EDGAR

1970-2023年全球温室气体排放 GHG 数据集 EDGAR

WW、forever的博客 1172

自动生成MVC中的Service层、Dao层及Model层

项目流程 从GenerateConf.xml读取一些必要数据,如路径、实体类名、实体类字段等,在Generate.java这个总控制中心解析后,调用GenerateDao、GenerateService和GenerateModel类的中方法生成所需代码。 在PathUtil中,有一些公共的方法,如判断包路径是否存在,及将模板文件生成为java文件。以下代码可点击这儿下载代码模板文件dao.ftl

以博促学 1万+

2 中望CAD二次开发-绘制图形(ZRX C++)

本文讲解中望CAD二次开发,关于块的概念及基本图形的绘制

cilvsuanna的博客 411

erlang中gen_server/gen_fsm使用hibernate

简单的理解:  hibernate可以使你闲置的erlang进程马上进行gc,因为进程处于receive状态下是不会gc的  我在性能调优时发现,gc对于消息发送速度的影响还是非常大的  关于erlang gc问题也可以参看这个  引用 Recently, as part of RabbitMQ server development, we ran into an i

oklizy的专栏 1832

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Erlang OTP四大行为模式之一gen_server解析和案例

在刚接触otp gen_server时很多人可能只是对着Erlang程序设计中的案例敲一遍,但对为什么要使用gen_server以及里面各个方法是如何联系和影响进程的估计都不太清楚。 首先讲下行为模式,你可以理解为面向对象中的设计模式(更像是模版方法模式),本质都是为了代码复用,当然你也可以把这些行为理解成为某种应用程序框架。我们往往在创建一个进程执行任务时都会有一下步骤, 1.spawn创建...

qq_35218302的博客 1576

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

erlang四大behaviour之一gen_server(转载)

erlang程序设计里面有个设计原则就是把你的进程构造成树,把共用代码提出来,特定功能用自己的module实现,这也就是behaviour了,应用behaviour可以减少与本身事务无关的代码量,设计逻辑更加清晰。老纪边学习边记录吧。 gen_server实现服务器/客户端模型,用于多个客户共用一个资源的这种情况。他由几个接口函数和几个回调函数组成(回调函数必须在你的module里定义...

CHXRUC1993的博客 254

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

在gen_server使用ets实例演示

Erlang的ETS(Erlang term storage)是一种在内存中存储数据的结构,类似于其他语言中的数据库。它允许你在Erlang程序中存储和检索数据。gen_server是Erlang中用于创建服务器的一种模式,它能够处理并发的客户端请求。以下是在gen_server首先,我们可以在gen_server的init函数中使用在这个例子中,我们创建了一个新的ETS表,并将其命名为"state"。

qq_53795917的博客 688

虚拟银行 ErlyBank 与 gen_server

转载:[url]http://apps.hi.baidu.com/share/detail/6732177[/url] 本文是介绍Erlang/OTP系列文章的第一篇。 场景:银行ErlyBank的服务器开始运行,银行要求它成为可伸缩的系统,以便管理重要的顾客帐户。听说了Elang的强大功能后,银行雇用我们建造这一系统。为了测验我们的能力,银行首先要求我们建个简单的服务器,处理银行帐户...

工欲其善必先利其器 236

gen_server的一些心得

gen_server并不是我原来概念中的tcp_server或者udp_server的概念,只是一个纯粹的消息服务器,另外,附上它的一些回调函数的简单说明参考地址 http://hi.baidu.com/software_one/item/f5b07aeda3ac61215a2d64cd ● init/1 - 服务器的初始化; ● handle_call/3 - 处理对服务器的同步调...

weixin_30235225的博客 81

[代码分析]gen_server例子分析

这个例子是erlang/OTP并发实践里的  例子内容很简单 但是对行为不是很理解的人(比如我)读起来还是有那么一点点困难的   源代码: https://raw.github.com/erlware/Erlang-and-OTP-in-Action-Source/master/chapter_03/tr_server.erl     这边简化一下 do_rpc()那个函数其实就...

Fair_Jm的专栏 260

[Erlang脚印 0004] gen_server

gen_server:start_link(ServerName, Module, Args, Options) -> Result ServerName={local, Name}|{global, GlobalName}|{via, Module, ViaName} Option = {debug, Dbgs}|{timeout, Time}|{spawn ...

weixin_33697898的博客 97

erlang四大behaviour之一gen_server

来源:http://www.cnblogs.com/puputu/articles/1701017.html erlang程序设计里面有个设计原则就是把你的进程构造成树,把共用代码提出来,特定功能用自己的module实现,这也就是behaviour了,应用behaviour可以减少与本身事务无关的代码量,设计逻辑更加清晰。老纪边学习边记录吧。 gen_server实现服务器/客户端模...

weixin_30527143的博客 85

OTP设计原则用户手册学习笔记一:Gen_Server Behaviour

Erlang代码   %Gen_Server Behaviour(Gen_Server行为)   %客户端-服务器模型通常是一个服务器和多个客户端。   %通常用于资源管理系统,多个客户端共享相同的资源,   %服务器则管理这些资源。      %   %Gen_Server Behaviour实例:   %   -module(gen_server_behaviou

952

Erlang入门:gen_server代码模板

%% gen_server代码模板 -module(myserver). -behaviour(gen_server). % -------------------------------------------------------------------- % Include files % -----------------------------------------

Rolong的博客 1605

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

http://blog.sina.com.cn/s/blog_3fe961ae0101k4p6.html 行为模式其实非常类似于面向对象语言中的接口,至少笔者是这么理解的。OTP行为模式将一些反复出现的模式分成了两个部分,通用部分和具体应用相关的实现部分,这一过程其实就类似于面向对象编程中的抽象出接口的过程。本文给出一个OTP中最常见的行为模式的示例:通用服务器,即gen_server。 编写...

weixin_30721077的博客 136

[Erlang 0023] 理解Erlang/OTP gen_server

Erlang的OTP behaviour是对一些通用编程模式的抽象,在用Erlang 语言做开发时可以在behavior基础上快速构建出可用且可靠的功能.OTP behaviour包含gen_server gen_event gen_fsm supervisor.其中绝大多数情况下都是在使用gen_server,supervisor本身也是使用gen...

weixin_34356555的博客 162
下一篇: 学习record相关知识
erlang_hell
博客等级 码龄14年 57粉丝 89原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值