`
bachmozart
  • 浏览: 111330 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

hibernate your gen_fsm process

阅读更多
关于erlang进程hibernate的好处,去过这次erlang大会的同学应该已经都知道了

简单的理解:
hibernate可以使你闲置的erlang进程马上进行gc,因为进程处于receive状态下是不会gc的
我在性能调优时发现,gc对于消息发送速度的影响还是非常大的

关于erlang gc问题也可以参看这个
引用

Recently, as part of RabbitMQ server development, we ran into an interesting issue regarding Erlang’s per-process garbage collection. If a process is idle — not doing any work at all, simply waiting for an external event — then its garbage-collector will not run until it starts working again. The solution is to hibernate idle processes, which causes a very aggressive garbage-collection run and puts the process into a suspended state, from which it will wake when a message next arrives.


所以查看rabbitMQ源代码可以看到里面的gen_server/fsm等进程统统都会使用hibernate

下面解释下如何让进程hibernate,这里需要注意的是一个进程hiberate后,会清空stack栈,也就是说之前的调用关系全部没有了,也就是说hibernate所在的函数永远不会返回,待有新消息时,进程从hibernate(M,F,A)里指定的M:F处开始运行

gen_server和gen_fsm都提供了hibernate的方式,2种方法

第一种:
在gen_server,或gen_fsm回调接口返回时,指定hibernate
{next_state, NStateName, NStateData, Time1} 

实际这个Time1可以指定为hibernate,则重新回到main loop时会直接hibernate

这种方法可能使你的进程频繁hibernate又被唤醒,效率不是很好

正确的方式应该是,当你预期你的进程一段时间内不会收到消息才hibernate

所以推荐下面的方法,直接看下示例代码:
%% ====================================================================
%% Interface Function
%% ====================================================================
join(UserId)->
	io:format("join UserId=~p~n",[UserId]),
	gen_fsm:sync_send_event(?MODULE, {join,UserId}).

start()->
	gen_fsm:send_event(?MODULE,start).

%% ====================================================================
%% Callback Function
%% ====================================================================
wait_player({join,UserId},_From, State) ->
	print_inner_data(State),
	put(p,get(p)+1),
	ets:insert(State#state.players,{p,UserId}),
	Count=State#state.count+1,
	if
		Count =:= 3 ->
			io:format("jump to next phrase -> start~n"),
			{reply,next_phrase,wait_start,State,5000};
		true->
			NewState=State#state{count=Count},
			{reply,stand_still,wait_player,NewState,5000}
	end.
wait_player(timeout,State)->
	io:format("timeout happened when wait_player,let's hibernate~n"),
	proc_lib:hibernate(gen_fsm, enter_loop, [?MODULE, [], wait_player,State]).

wait_start(start,State)->
	 print_inner_data(State),
	 io:format("recv start event ~n"),
	 {next_state,wait_start,State,5000};

wait_start(timeout,State)->
	io:format("timeout happened when wait_start,let's hibernate~n"),
	proc_lib:hibernate(gen_fsm, enter_loop, [?MODULE, [], wait_start,State]).

start_link()->
	gen_fsm:start_link({local,?MODULE}, ?MODULE, [] ,[]).

init([])->
	put(p,0),
	{ok, 
		wait_player, 
		#state
		{
			count=0,
			players=ets:new(players,[bag])
		},
		5000
	}.

print_inner_data(State)->
	io:format("inner data: dict=~p,ets=~p~n",[get(p),ets:tab2list(State#state.players)]).



运行:
2> {ok,Pid}=fsm:start_link().
{ok,<0.39.0>}

3> process_info(Pid,total_heap_size).
{total_heap_size,233}

4> fsm:join(123).
join UserId=123
inner data: dict=0,ets=[]
stand_still
timeout happened when wait_player,let's hibernate

5> process_info(Pid,total_heap_size).
{total_heap_size,33}

6> fsm:join(456).
join UserId=456
inner data: dict=1,ets=[{p,123}]
stand_still


总体上是让进程在main_loop里先timeout也就是证明一段时间内都没有消息到达,然后gen_fsm进程是发送{'gen_event',timeout}消息处理timeout事件的,所以要在每个Mod:StateName处都加个处理timeout的分支,来进行timeout处理,也就是hibernate掉自己,重新进入的是enter_loop 函数,这个东西很有用呐,大家可以查看源码,我就不多说了

另外,示例中可以看到,hibernate会清空stack,但是不会影响你的进程字典和ets等其它东西,可以放心用了










分享到:
评论
2 楼 rain2005 2010-01-14  
调用栈会清空,但是函数参数就是状态还是在的哦,good job
1 楼 mryufeng 2009-12-18  
gen_*系列 都支持hibernate, 会节约很多内存的...

相关推荐

    AXI_Master_FSM.rar_AXI_AXI implement_AXI master_AXI_Master_FSM_a

    在本压缩包文件"AXI_Master_FSM.rar"中,重点是实现了一个基于状态机(Finite State Machine, FSM)的AXI主设备(AXI Master)。 AXI主设备是AXI协议中的一个关键组件,它负责发起数据传输请求,控制读写操作,并...

    视频中工程代码 class8_FSM

    视频中工程代码 class8_FSM视频中工程代码 class8_FSM视频中工程代码 class8_FSM视频中工程代码 class8_FSM视频中工程代码 class8_FSM视频中工程代码 class8_FSM视频中工程代码 class8_FSM视频中工程代码 class8_FSM...

    otg_fsm.rar_FSM_otg

    `otg_fsm.rar_FSM_otg`这个标题暗示了我们讨论的是关于ChipIdea USB IP核心中的OTG FSM驱动程序。 `otg_fsm.c`文件很可能是实现这个驱动的核心代码,它包含了FSM的定义、状态转换逻辑以及与OTG相关的操作处理。在...

    Stepper_motor_fsm.rar_FSM_FSM vhdl_it_stepper motor

    标题中的“Stepper_motor_fsm.rar_FSM_FSM vhdl_it_stepper motor”表明这是一个关于步进电机(stepper motor)的文件,其中包含了状态机(Finite State Machine, FSM)的设计,设计语言为VHDL,这通常用于数字逻辑...

    fsm_hello_fsm_hello_FSM_

    标题中的"fsm_hello_fsm_hello_FSM_"似乎是一个与有限状态机(Finite State Machine,FSM)相关的项目或文件命名约定,其中"hello"可能代表一个示例或特定的模块,而"FSM"是有限状态机的缩写。在描述中,我们只有一...

    textsearch_fsm.rar_FSM

    标题中的"**textsearch_fsm.rar_FSM**"表明这是一个与文本搜索相关的有限状态机(Finite State Machine, FSM)项目,而文件"**ts_fsm_token**"则是该机器中用于处理状态转换的关键组件,称为“状态机令牌”。...

    or-c1_fsm_cn_final_060112.pdf

    ### OR-C1机型维修手册知识点总结 #### 一、安全注意事项 **1.1 防止人身伤害** - 在拆卸或组装机器及其配件前,必须先切断电源。 - 插座需位于机器附近且方便操作。 - 即使主电源关闭,机器和纸盘的某些部分也...

    erlang OTP Design Principles之Gen中文

    Erlang OTP设计原则中的Gen_Fsm行为是一个关键的概念,用于构建健壮、可扩展的并发应用程序。Gen_Fsm,即通用有限状态机,是一种行为模式,它提供了一种结构化的方法来处理具有多种状态和事件的系统。本文将深入探讨...

    FSM.rar_FSM_FSM MATLAB

    标题中的"FSM.rar_FSM_FSM MATLAB"表明这是一个与MATLAB相关的文件,重点在于"FSM",它可能是“Focal Spot Measurement”的缩写,因为描述中提到了"Measurement of focal spot size using knife edge method",这...

    fsm.rar_FSM_FSM code in vhdl_FSM vhdl

    有限状态机(Finite State Machine, FSM)是一种在数字系统设计中广泛应用的概念,特别是在VHDL(Very High Speed Integrated Circuit Hardware Description Language)编程中。VHDL是一种用于电子设计自动化(EDA)...

    fsm.rar_ FSM verilog_FSM_fsm二段式_状态机_状态机写法

    状态机(Finite State Machine, FSM)是数字系统设计中的核心概念,特别是在Verilog这样的硬件描述语言中,状态机被广泛用于实现控制逻辑。本资源"FSM.rar"提供了一种详细的学习材料,专注于不同类型的Verilog状态机...

    基于Erlang的gen_tcp聊天室代码,功能完整

    - 处理连接请求,为每个新连接创建一个新的进程(通常是一个gen_server或gen_fsm行为)。 - 注册和登录逻辑,处理用户认证请求。 - 监听和转发消息,确保消息在正确用户间传递。 - 错误处理和异常恢复,确保系统的...

    PyPI 官网下载 | gevent_fsm-0.2.0.tar.gz

    《PyPI官网下载 | gevent_fsm-0.2.0.tar.gz:深入解析Python异步编程与状态机库》 在Python的世界里,高效的并发处理是开发者常常面临的一个挑战。为了解决这个问题,Python社区提供了丰富的库,其中就包括了`...

    FSM.rar_FSM_FSM状态机_FSM规范_三段式状态机_状态机

    状态机(Finite State Machine, FSM)是计算机科学和软件工程中的一个重要概念,它是一种数学模型,用于描述系统在不同状态间的转换。在这个压缩包“FSM.rar”中,包含了一个特别规范化的FSM状态机模板,它采用了三...

    Python库 | oarepo_fsm-1.6.7-py2.py3-none-any.whl

    **Python库oarepo_fsm-1.6.7-py2.py3-none-any.whl详解** 在Python编程中,库是开发者的重要工具,它们提供了丰富的功能,帮助我们更高效地编写代码。`oarepo_fsm`是这样一个库,专注于状态机(Finite State ...

    fsm.rar_FSM_V2

    "fsm.rar_FSM_V2" 提供的资源显然是一个关于Linux环境下有限状态机的实现,版本为2.13.6。下面将详细解释FSM的基本概念,以及在Linux中的应用。 有限状态机是一种数学模型,用于描述一个系统随时间变化的行为。它由...

    fsm.zip_FSM_FSM example_zip

    在这个"FSM_example.zip"压缩包中,我们可以预见到包含了一个关于有限状态机的具体示例。 在计算机编程中,有限状态机常用于处理具有固定数量可能状态的问题,如解析语言、网络协议、游戏逻辑等。FSM通常由以下部分...

    Python库 | django_workflow_fsm-3.1.1-py2.py3-none-any.whl

    **Python库 django_workflow_fsm**是针对Django框架的一个强大工具,专为实现工作流管理而设计。这个库的版本为3.1.1,适用于Python 2和Python 3环境,其whl文件名为"django_workflow_fsm-3.1.1-py2.py3-none-any....

    fsm.rar_FSM_FSM vhdl_状态机

    状态机(Finite State Machine, FSM)是数字系统设计中一种重要的概念,特别是在VHDL这样的硬件描述语言中,它被广泛用于实现各种控制逻辑。在本压缩包“fsm.rar”中,我们可以看到一系列与FSM相关的VHDL代码实例,...

    fsm.zip_FSM实例_fsa_fsm例子

    **有限状态机(Finite State Machine, FSM)**是一种数学模型,用于描述系统或程序在不同状态之间转换的行为。在计算机科学、软件工程以及自动化控制等领域,FSM有着广泛的应用。这个压缩包`fsm.zip`包含了关于FSM的...

Global site tag (gtag.js) - Google Analytics