gen_server模块

gen_server实现 阅读erlang gen_server源码,分析 阅读详情

Erlang资料资料整理

在《Programming Erlang》的OTP introduction章节中,作者通过循序渐进的方式,向我们展示了gen_server设计思路,现在做下总结: 


在具体看gen_server之前,我们先看一个server通用框架: 


在这个server里,你几乎看不到任何和具体功能相关的东西,它只提供了一个server所具备的基本框架,那它是如何运行的呢? 
当我们调用start函数时,就启动了一个服务,如果服务器接收到一条消息,那么它将会把这条消息转交给Mod:handle_call或者Mod:handle_cast处理 ,然后把执行结果返回给客户端(可选),接着继续等待新消息。 

从这个过程中我们不难发现,服务器实际上充当着“代理”的角色,而真正处理客户端请求的其实是另外一个Module(我们称之为:callback模块)  

这样有什么好处呢? 我谈谈自己的拙见: 
1.解耦,把服务器功能部分和非公能部分分离,这样可以我们就可以更加专注于服务器功能模块的编写(即callback模块) 
2.复用性,如果我们希望开发一个具有新功能的server,我们可以复用现有的server框架,然后编写具有新功能的callback Module即可 

现在我们看一个callback Module例子(它提供了KV存储功能) 
 

其中init, handle_call方法是用来供server端回调的,而add,find,start方法是供客户端调用的 

我们看下执行结果: 
 

现在我们来简单分析下整个执行流程:  
stroage:start() 启动了一个名为kv_server的服务,并且使用storage模块作为该服务的callback Module, 接着就阻塞在loop方法中,等待着新消息的到来....这时候,当我们调用storage:add(name, diaocow),就向kv_server发送了一条请求消息{add, name, diaocow},当kv_server接受到这条消息后,自己并没有处理,而是转交给他的callback模块storage处理,并且把处理后的结果返回给客户端,,然后继续等待着新消息... 

可以看出server模块充当着代理的角色(接受客户端消息 -> 发给callback模块处理 -> 将处理结果返回给客户端),而storage模块一方面给server提供callback(真正负责处理客户端请求),另一方面给客户端提供了可以调用的接口(譬如这里的add和find接口)。 

当你需要修改这个server的功能时,只需要修改callback模块即可,是不是非常方便呢  ^_^ 


---------------------------------------------------------------------华丽分割线-------------------------------------------------------------------  


说了那么多,那么gen_server到底是什么呢? 其实它提供了类似上述理念的通用server框架,只不过比我们更加稳健,完善,如果你需要编写具有某个功能的server,使用gen_server可以让你专注于功能本身的编写,即callback模块 

那如何编写一个gen_server的callback模块呢?只需三步 
1.给你的callback Module起一个名字 
2.确定需要向外界(客户端)提供的接口 
3.实现gen_server所要求的回调接口
 
  
现在我们使用gen_server重新实现一下KV存储 


运行下程序,一切ok 
 

现在我们就详细解释下new_storage模块中每个方法的作用: 

1.-behaviour(gen_server) 
它表示让编译器检查,当前module是否实现了gen_server指定的所有回调接口,若我注释掉某一个回调接口(譬如code_change/3),编译时会报: 
 

2.gen_server:start_link(ServerName, Module, Args, Options) -> Result  
这个方法用来启动一个server,其中: 
参数ServerName指定了服务名 
参数Module指定了该server的callback模块 
参数Args将作为服务初始化的启动参数(服务初始化时会调用:Module:init([Args])) 
参数Options指定了一些特性参数,通常可以直接使用[] 

如果服务启动成功,返回{ok, Pid} 

3.Module:init([Args])  
这个方法会在服务初始化时被回调,参数Args就是gen_server:start_link中倒数第二个参数,若初始化成功,该方法放回{ok, State},其中State将作为启动服务的State 

4.gen_server:call(ServerRef, Request)  
这个方法供callback模块向ServerRef代表的服务发送Request请求(callback模块通常会在之上再封装一层接口供客户端调用,譬如这里的add,find方法),注意该方法是一个 同步调用 ,它会一直等待服务器返回一个响应消息(除非等待超时,默认5s) 

5.Module:handle_call(Request, From, State) -> Result  
这是一个回调方法,用来处理gen_server:call(ServerRef, Request)发出的请求,其中: 
Request,表示客户端请求 
From,表示请求来自哪个客户端 
State,表示当前服务器状态 

Result为handle_call 请求处理结果,它有以下几种类型 
{reply,Reply,NewState} 
{reply,Reply,NewState,Timeout} 
{reply,Reply,NewState,hibernate} 
{noreply,NewState} 
{noreply,NewState,Timeout} 
{noreply,NewState,hibernate} 
{stop,Reason,Reply,NewState} | {stop,Reason,NewState} 

这几种返回值有什么区别呢? 
如果返回的是以reply开头,那么Reply将会作为响应返回给客户端 
如果返回的是以noreply开头,那么服务器将不会返回任何消息给客户端(这会导致客户端阻塞,因为客户端调用的gen_server:call方法是一个同步调用,当它发出请求后,会一直等待服务器发送响应消息,除非等待超时) 

6.gen_server:cast(ServerRef, Request)  
这个方法同gen_server:call(ServerRef, Request),但它最大的区别就是该调用是 异步的 ,它不需要等待服务器返回任何处理结果 

7.Module:handle_cast(Request, State) -> Result  
这个方法用来处理gen_server:cast(ServerRef, Request)发出的请求,由于不会返回结果给客户端,所以参数列表中也没有From 

关于gen_server更多api,请参看: http://www.erlang.org/doc/man/gen_server.html  
otp官方文档: http://www.erlang.org/doc/design_principles/gen_server_concepts.html  


现在我们已经把gen_server设计的大体思想说了一遍,即:gen_server实现了一个通用server框架,若我们需要开发某功能,只需要按照gen_server回调接口规范,编写相应的callback Module即可 
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 的状态转换是由事件驱动的。 阅读详情

相关推荐

深入理解Erlang OTP中的gen_server模块

本文深入探讨了Erlang OTP系统中的gen_server行为模块,通过逐步构建一个通用服务器的过程,揭示了 OTP 如何将问题的非功能部分与功能部分分离。文章通过从一个基础服务器模型开始,逐步引入事务处理、热代码交换等特性,最终展示了一个集成了这些特性的完整服务器模型。这一过程不仅有助于理解OTP中的抽象构建过程,还为如何在自己的项目中构建自定义抽象提供了洞察。

weixin_28888459的博客 514

[Erlang] - gen_server

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

偶尔来看看 895

【实战技巧】matplotlib中文标签显示问题的3种高效解决方案

本文详细介绍了解决matplotlib中文标签显示问题的3种高效方法,包括修改字体设置、临时指定字体和修改后端配置。针对不同操作系统和环境提供了实用技巧,帮助开发者快速解决中文显示为方框的常见问题,提升数据可视化效果。

weixin_30855099的博客 170

ETS 和 gen_server 的使用

ETS和DETS表保存的是元组。元组里的某一个元素(默认是第一个)被称为该表的键。通过键来向表里插入和提取元组。当我们向表里插入一个元组时会发生什么,取决于表的类型和键的值。一些表被称为set,它们要求表里。另一些被称为同键表bag,它们允许。ets有4种类型的table,如表所示:基本的表类型(异键表和同键表)各有两个变种,它们共同构成四种表类型:异键、有序异键(ordered set)、同键和副本同键(在异键表里,各个元组里的键都必须是独一 无二的。

qq_53795917的博客 288

Keras中LSTM输入数据重塑与预处理实战指南

LSTM(长短期记忆网络)作为循环神经网络的重要变体,在时间序列建模中发挥着关键作用。其核心原理是通过门控机制学习长期依赖关系,而输入数据的正确重塑是实现这一功能的基础。在Keras框架中,LSTM要求输入数据必须组织成(samples, timesteps, features)的三维张量结构,这与传统全连接网络的处理方式截然不同。从工程实践角度看,合理的数据预处理能显著提升模型性能,特别是在处理温度预测、股票价格分析等时间序列任务时。常见的数据源如CSV文件、图像序列等都需要特定的转换方法,包括使用Tim

weixin_42300144的博客 305

STM32_DAC

DAC(Digital-to-Analog Converter,数模转换器)是将数字信号转换为模拟信号的外设,广泛应用于音频输出、波形生成、电机控制等场景。STM32F407 系列芯片配备了 2 个 DAC 通道(DAC1 和 DAC2),支持 12 位分辨率,支持多种触发方式,可输出稳定的模拟电压。本文从 DAC 的基本原理出发,详细讲解 STM32F407 DAC 的配置方法、代码实现、波形生成以及实际应用案例,帮助你快速掌握 DAC 的使用技巧。

轩宇的博客 1240

erlang学习笔记之gen_server 入门

以下三点是编写gen_server回调模块的简要步骤:(1) 确定回调模块名。(2) 编写接口函数。(3) 在回调模块里编写六个必需的回调函数。

keyzx的博客 181

Python+whisper/vosk实现语音识别

Whisper 是一个由 OpenAI 开发的人工智能语音识别模型,它能够将语音转换为文本。Whisper 模型特别之处在于它的设计目标是能够理解和转录多种语言的语音,包括但不限于英语。Whisper 模型在训练时使用了大量不同语言的语音数据,这使得它具有很好的跨语言能力。Vosk 是一个开源的语音识别库,它可以在离线环境下工作,不依赖于任何外部服务。Vosk 基于Kaldi语音识别框架,支持多种语言,包括中文。Vosk提供了多种预训练模型,可以根据需求选择适合的模型进行语音识别。

weixin_44458771的博客 5939

【Erlang】二十五、OPT——gen_server模块

gen_server模块回调模块1. 回调模块必须导出六个回调方法2. 回调模块范例 回调模块 1. 回调模块必须导出六个回调方法 init/1 handle_call/3 handle_cast/2 handle_info/2 terminate/2 code_change/3 2. 回调模块范例 -module(gen_server_handle). %% gen_server 迷你版本 -behaviour(gen_server). -export([start_link/0]). %% 启动服

Coco的博客 539

北斗导航 | 卡尔曼滤波与因子图优化对比(附图优化matlab代码)

- 历史数据利用:因子图通过滑动窗口保留历史状态,优化时联合多帧数据;卡尔曼滤波仅依赖当前和上一帧状态 。 - 迭代优化:因子图通过多次迭代逼近最优解,卡尔曼滤波仅单次更新 。 - 误差抑制:因子图的多次线性化可有效抑制非线性误差(如GNSS伪距观测的非线性) 。

尘世冰封的专栏 1303

SAP Group Reporting入门指南(11)--配置

这里选择的是FS项目目标属性,FS项目有四个目标属性,比如上图配置的是抵消目标属性,所以就去找触发FS项目的抵消目标属性配置的是哪个FS项目,就以这个FS项目作为贷方。这里选择的是FS项目目标属性,FS项目有四个目标属性,比如上图配置的是抵消目标属性,所以就去找源FS项目的抵消目标属性配置的是哪个FS项目,就以这个FS项目作为借方。例如,添加一个包含用于存储百分比的 FS 项的选项。这里选择的是FS项目的角色属性值,如果这里定义了,那么就从FS项目中找到FS项目角色属性值与之匹配的FS项目作为贷方。

bflyfish的博客 568

erlang学习: 基于gen_server的echoserver及监控模块

第一版基础上,将echoserver融入OTP:gen_server框架 同时引入OPT:supervisor行为包,实现对 echoserver的监控模块 当 echoserver退出后,监控模块master可以重启之。 erlang的监控树绝对是精华所在,解决了分布式开发的一个重要的问题域 [code="erlang"] -module(es2). -behavio...

独立思考 204

uniapp - 鸿蒙真机运行报错hvigor ERROR: Failed :entry:default@CompileArkTS...,hvigor ERROR: default@CompileAr

uniapp鸿蒙报错> hvigor ERROR: Failed :entry:default@CompileArkTS... hvigor ERROR: default@CompileArkTS watch work[0] failed. 【HarmonyOS】工程编译后报错hvigor ERROR: Failed :entry:default@CompileArkTS,uniAPP鸿蒙开发无法编译运行启动报错,工程编译后报错,运行不起来,删除掉项目entry下的build和.preview缓存文件后重新

🏆 前端领域优质创作者 4790

Erlang模块gen_server翻译

gen_server 概要:   通用服务器行为描述:   行为模块实现服务器的客户端-服务器关系。一个通用的服务器进程使用这个模块将实现一组标准的接口功能,包括跟踪和错误报告功能。它也符合OTP进程监控树。了解更多信息参考OTP设计原则。   gen_server假定所有特定部分位于一个回调模块,它导出的一组预定义的功能。行为函数和回调函数的关系可以说明如下:   gen_server...

weixin_30764137的博客 146

YOLO26涨点改进 | 全网独家创新、检测头Head改进篇 | AAAI 2026 | 使用StripConvHead改进YOLO26的检测头,处理小目标、遮挡小目标检测有效涨点,助力高效发论文

🔥本文给大家介绍使用StripConv条形卷积改进 YOLO26的检测头,可以显著提高模型在高纵横比物体检测、目标定位和多尺度物体检测方面的表现。StripConv条形卷积能够更有效地捕捉细长物体的特征,提升定位精度,并通过简化卷积核设计减少计算冗余,优化计算效率。此外,该改进增强了 YOLO26对复杂场景和实时任务的适应能力,特别适用于遥感图像目标检测、小目标检测等领域。具体怎么使用请看全文。摘要:随着遥感物体检测的快速发展,检测高纵横比物体仍然是一个挑战性问题。

Ai缝合怪、助力小伙伴高效发论文 268

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

erlang中文手册——gen_server

声明:本文章是对erlang手册的部分内容的中文翻译,版权归原作者所有……由于本人的英语水平有限(翻译此手册的目的之一就是提高英语水平^0^),所以翻译有误乃正常现象,如有发现请及时提醒,THX…… 谨以此文献给初学erlang并且不喜欢看英文手册的朋友……     gen_server 模块         gen_server 模块摘要       通用服务器

erlang--服务器的未来 8036

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Erlang OTP(五) gen_server小结

通用服务器模块(gen_server) 回调模块(my_bank)当回调函数调用失败或返回错误值时,gen_server会中止。gen_server不会自动跟踪退出信号。

m0_54103484的博客 689

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

gen_server的回调结构(上)

我们已经见过了gen_server:call和handle_call之间的交互,它的作用是实现远程过程 调用。gen_server:cast(Name, Msg)则实现了一个播发(cast),也就是没有返回值的调用(实 际上就是一个消息,但习惯上称它为播发来与远程过程调用相区分)。gen_server:start_link(Name, Mod, InitArgs, Opts)这个调用是所有事物的起点。它 会创建一个名为Name的通用服务器,回调模块是Mod,Opts则控制通用服务器的行为。

weixin_48092769的博客 185

erlang OTP gen_server 图解分析

在阅读erlang的otp源码gen_server.erl的时候,一直想写点什么,用一种最好的方式表达出来,最终却总是没法表达清楚,困惑之余看到这篇文章,作者用图解的方式,非常清晰明了的表达了我一直想表达的东西,下面是原文链接:http://www.hoterran.info/otp-gen_server-sourcecode感谢原创作者热心的分享。阅读OTP源码可以帮助你写出更好、更健壮的erl...

Atuforever的博客 412

gen_server 入门

以下三点是编写gen_server回调模块的简要步骤。(1) 确定回调模块名。(2) 编写接口函数。(3) 在回调模块里编写六个必需的回调函数。按部就班,我们将编写一个简单的支付系统。把这个模块称为my_bank。

weixin_48092769的博客 172

【转载】gen_server 边缘

我们以 Module 代表 gen_server 的 callback 模块1, 实现 gen_server behaviour 的模块会产生一个新的 process 么?毫无疑问,太会了!通过调用 proc_lib:start_link/5 创建 process 。2, gen_server:start_link/3,4 中的 Options 参...

weixin_34228662的博客 92

OTP gen_server

erlang behaviour小结之gen_server OTP入门 分类:Erlang2012-08-06 18:55867人阅读评论(0)收藏举报 servererlangcallback框架服务器编程 首先清楚gen_server提供C/S架构中的服务端的实现,即定义了自己一套规范的服务器框架。 ...

weixin_34413103的博客 98

Erlang OTP之gen_server入门

1.概念 gen_server是对一种服务器开发模式的抽象,在我们日常开发中,其实有很多行为都是重复的,例如我们会用一个loop()来不断使服务器进入一种处于等待,处理信息,返回结果,等待的状态。其实这些工作都是重复的,而一个行为就是把我们这些重复的工作都抽象出来,简化工作。 2.函数介绍 我们常用的函数有以下几个: 1.start() -> gen_server:sta...

fbher的博客 601

[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
上一篇: mysql中key 、primary key 、unique key 与index区别
下一篇: PHP 设计模式之单例模式
Hx_Moon_
博客等级 码龄14年 94粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值