虽名为通用服务器,但gen_server的代码并不天生具有处理并发请求的能力,实际上一个gen_server写成的模块是运行在一个线程中的,所有针对它的请求都是序列化处理的,因此gen_server并不具有自动并行处理的能力,还得靠程序员自己实现并行。
熟悉OOP的程序员可能会误用gen_server,例如让一个gen_server的模块持有系统的配置信息,每当需要配置信息时就通过gen_server:call(或者cast)这个模块得到,但问题是如果大量的并行进程同时请求配置信息,这些并行请求就会在这里排队然后一个个的序列化调用从而阻塞原来本是并行的程序。
最简单的处理方法是处理逻辑另开一个线程执行,然后返回{noreply, State},例如:
handle_call(Req, From, State) ->
Handler = State#state.store_handler,
spawn(fun(Req) ->
Res = ......, % 在此处理计算得到结果
gen_server:reply(From, Res) % 将结果返回给调用者
end),
{noreply, State}; % 直接返回
而调用者的执行方式不变:
gen_server:call(?SERVER, Req)
这是个同步调用,会等待在handle_call中新开的进程的计算结果返回后才继续执行下一步操作。
在
scalaris的设计中,配置信息由config模块管理,该模块类似于gen_server,在系统引导时会启动此服务模块进程,然后将服务器进程挂在boot_sup监督树上:监督树启动它时会spawn一个进程,这个进程首先创建一个受保护的ets命名表,随后把配置信息导入到这个表中,然后进入一个什么事都不做的“死循环”。创建ets表的进程是表的所有者,如果所有者进程死掉,表的内存空间就会被释放。
这个ets表就像一个黑板,任何人只有知道这个黑板的名字就可以阅读黑板的内容。看代码:
start_link(ConfigFiles) ->
Owner = self(),
Link = spawn_link(?MODULE, start, [ConfigFiles, Owner]),
receive
done ->
ok;
X ->
io:format("unknown config message ~p", [X])
end,
{ok, Link}. % Link代表的进程将被挂在监督树下
%@private
start([File], Owner) ->
catch ets:new(config_ets, [set, protected, named_table]),
populate_db(File), % 从配置文件中读取配置信息并导入到ets表config_ets中
Owner ! done,
loop(). % 服务器进程进入死循环状态
loop() ->
receive
_ ->
loop()
end.
而中couch中,管理配置信息的模块也是采用ets保护表保存,但是一个gen_server behaviour的模块,获取配置时直接从命名表中读取配置信息,修改配置时就是通过gen_server:call进行设置。
分享到:
相关推荐
首先,gen_server是一个行为(behaviour),它定义了一组回调函数,这些函数必须由实现gen_server行为的模块实现。这些回调函数包括`init/1`、`handle_call/3`、`handle_cast/2`、`handle_info/2`、`terminate/2`和`...
在Erlang编程语言中,`gen_server`行为是一个强大的模块,用于构建具有状态的、容错的服务。这篇名为“gen_server tasting 之超简单名称服务”的博客文章可能介绍了如何利用`gen_server`来实现一个简单的命名服务。...
开源项目-clanchun-genserver.zip,GitHub - clanchun/genserver: A minimal generic server that implements Erlang's gen_server behaviour.
-behaviour(gen_server). %% gen_server callbacks -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). init(Args) -> {ok, UdtSocket} = gen_udt:open(), {ok, {...
桥梁结构
gimbal_behaviour.c
-behaviour(gen_server). start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). init([]) -> {ok, State}. handle_call(Request, From, State) -> %% 处理请求的逻辑 {reply, ...
- **2.2 Gen_Server Behaviour**:文档缺失,未提供具体细节。 - **2.3 Gen_Fsm Behaviour**:讲解如何使用有限状态机行为。 - **2.3.1 有限状态机**:Erlang中的Gen_Fsm行为允许实现有限状态机。 - **2.3.2 实例*...
《Fractal Behaviour of the Earth System》由V. P. Dimri编辑,并由D. L. Turcotte教授撰写前言,该书深入探讨了分形理论在地质学与固体地球物理学领域的应用。通过收集一系列论文,本书详细阐述了地球大陆地壳的...
### P2P_Behaviour_Detection #### Peer-to-Peer (P2P) Behaviour Detection by TCP Flows Analysis **背景与重要性** 随着互联网技术的发展,P2P(Peer-to-Peer)应用变得越来越普遍,如Gnutella、Kazaa、...
-behaviour(gen_server). %% gen_server callbacks -export([init/1, terminate/2, code_change/3, handle_call/3, handle_cast/2, handle_info/2]). -dialyzer([no_behaviours]). %%%==========...
- **Gen_Server Behaviour**: - **定义**: Gen_Server 是OTP中最常用的Behavior之一,用于创建通用服务器进程。 - **特性**: 支持请求处理、状态管理、错误恢复等功能。 - **Gen_Fsm Behaviour**: - **有限状态...
### 动态系统行为探索:并行与分布式仿真系统 #### 标题解析 标题“Modeling and Simulation: Exploring Dynamic System Behavior”(建模与仿真:探索动态系统行为)指出本文档的主要研究方向是通过建模和仿真技术...
具体分析步骤以及结果见“ User_Behaviour_Analysis.ipynb” 数据太大,请至官网自行下载: ://tianchi.aliyun.com/dataset/dataDetail?dataId=42 项目简介 本项目初步分析电商用户(以淘宝为例)的用户行为,并在为...
NAPLAN与学术数据的行为分析我在昆士兰教育中心办公室的影子工作中于2019年底完成了这个项目。 在我的最后一周,我完成了FNQ学校的NAPLAN和行为分析,以协助2020年(2017-2019)的过去三年中的7年级学生的管理人员。...
本项目中主要利用了OTP提供的行为(behaviour),如`gen_server`,用于简化服务端的开发。 - **gen_server行为**: - **定义**: 维护某个状态或提供某项功能的服务端行为。 - **应用场景**: 适合于需要维护状态的...
Animal_behaviour-Project 实时网络通信硕士论文 V0.1 将项目添加到GIT。 功能包括: 从服务器获取动物 在动物区接收动物 用户可以单击每种动物,并在此过程中创建一个具有动物名称的对象 V0.2 完成了get_...
在提供的"ML_Animal_Behaviour-master"压缩包中,读者可以找到这些案例研究的源代码,这为其他研究者提供了可复现和扩展的基础。源代码通常包含数据预处理、模型构建、训练、验证和结果解释等步骤,是深入理解机器...
通过`-behaviour(Behaviour)`,模块可以声明为特定行为的回调模块,如OTP标准行为`gen_server`、`gen_fsm`、`gen_event`和`supervisor`。 4.2.3 记录(Record)定义 使用`-record(Record, Fields)`定义记录,记录...