OTP设计原则:Gen_Event 行为

4 Gen_Event 行为


这一章应该与gen_event(3)结合起来看,gen_event(3)对所有接口函数和回调函数都有详细描述. 

4.1 事件处理原则

在OTP中, an event manager is a named object to which events can be sent. An event could be, for example, an error, an alarm or some information that should be logged.

In the event manager, zero, one or several event handlers are installed. When the event manager is notified about an event, the event will be processed by all the installed event handlers. For example, an event manager for handling errors can by default have a handler installed which writes error messages to the terminal. If the error messages during a certain period should be saved to a file as well, the user adds another event handler which does this. When logging to file is no longer necessary, this event handler is deleted.

An event manager is implemented as a process and each event handler is implemented as a callback module.

The event manager essentially maintains a list of {Module, State} pairs, where each Module is an event handler, and State the internal state of that event handler.

4.2 Example

The callback module for the event handler writing error messages to the terminal could look like:

 
java 代码
 
  1. -module(terminal_logger).  
  2. -behaviour(gen_event).  
  3.   
  4. -export([init/1, handle_event/2, terminate/2]).  
  5.   
  6. init(_Args) ->  
  7.     {ok, []}.  
  8.   
  9. handle_event(ErrorMsg, State) ->  
  10.     io:format("***Error*** ~p~n", [ErrorMsg]),  
  11.     {ok, State}.  
  12.   
  13. terminate(_Args, _State) ->  
  14.     ok.  


The callback module for the event handler writing error messages to a file could look like:

 
java 代码
 
  1. -module(file_logger).  
  2. -behaviour(gen_event).  
  3.   
  4. -export([init/1, handle_event/2, terminate/2]).  
  5.   
  6. init(File) ->  
  7.     {ok, Fd} = file:open(File, read),  
  8.     {ok, Fd}.  
  9.   
  10. handle_event(ErrorMsg, Fd) ->  
  11.     io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),  
  12.     {ok, Fd}.  
  13.   
  14. terminate(_Args, Fd) ->  
  15.     file:close(Fd).  
  16.       

The code is explained in the next sections.

4.3 Starting an Event Manager

To start an event manager for handling errors, as described in the example above, call the following function:

 
java 代码
  1. gen_event:start_link({local, error_man})  


This function spawns and links to a new process, an event manager.

The argument, {local, error_man} specifies the name. In this case, the event manager will be locally registered as error_man.

If the name is omitted, the event manager is not registered. Instead its pid must be used. The name could also be given as {global, Name}, in which case the event manager is registered using global:register_name/2.

gen_event:start_link must be used if the event manager is part of a supervision tree, i.e. is started by a supervisor. There is another function gen_event:start to start a stand-alone event manager, i.e. an event manager which is not part of a supervision tree.

4.4 Adding an Event Handler

Here is an example using the shell on how to start an event manager and add an event handler to it:

1> gen_event:start({local, error_man}).
{ok,<0.31.0>}
2> gen_event:add_handler(error_man, terminal_logger, []).
ok

This function sends a message to the event manager registered as error_man, telling it to add the event handler terminal_logger. The event manager will call the callback function terminal_logger:init([]), where the argument [] is the third argument to add_handler. init is expected to return {ok, State}, where State is the internal state fo the event handler.

 
java 代码
  1. init(_Args) ->  
  2.     {ok, []}.  


Here, init does not need any indata and ignores its argument. Also, for terminal_logger the internal state is not used. For file_logger, the internal state is used to save the open file descriptor.

 
java 代码
  1. init(_Args) ->  
  2.     {ok, Fd} = file:open(File, read),  
  3.     {ok, Fd}.  


4.5 Notifying About Events

3> gen_event:notify(error_man, no_reply).
***Error*** no_reply
ok

error_man is the name of the event manager and no_reply is the event.

The event is made into a message and sent to the event manager. When the event is received, the event manager calls handle_event(Event, State) for each installed event handler, in the same order as they were added. The function is expected to return a tuple {ok, State1}, where State1 is a new value for the state of the event handler.

In terminal_logger:

java 代码
 
  1. handle_event(ErrorMsg, State) ->  
  2.     io:format("***Error*** ~p~n", [ErrorMsg]),  
  3.     {ok, State}.  
  4.       
  5.   
  6. In file_logger:  
  7.   
  8. handle_event(ErrorMsg, Fd) ->  
  9.     io:format(Fd, "***Error*** ~p~n", [ErrorMsg]),  
  10.     {ok, Fd}.  

    

4.6 Deleting an Event Handler

4> gen_event:delete_handler(error_man, terminal_logger, []).
ok

This function sends a message to the event manager registered as error_man, telling it to delete the event handler terminal_logger. The event manager will call the callback function terminal_logger:terminate([], State), where the argument [] is the third argument to delete_handler. terminate should be the opposite of init and do any necessary cleaning up. Its return value is ignored.

For terminal_logger, no cleaning up is necessary:

  
java 代码
  1. terminate(_Args, Fd) ->  
  2.     file:close(Fd).  


For file_logger, the file descriptor opened in init needs to be closed:

 
java 代码
  1. terminate(_Args, Fd) ->  
  2.     file:close(Fd).  


4.7 Stopping

When an event manager is stopped, it will give each of the installed event handlers the chance to clean up by calling terminate/2, the same way as when deleting a handler.

4.7.1 In a Supervision Tree

If the event manager is part of a supervision tree, no stop function is needed. The event manager will automatically be terminated by its supervisor. Exactly how this is done is defined by a shutdown strategy set in the supervisor.

4.7.2 Stand-Alone Event Managers

An event manager can also be stopped by calling:

> gen_event:stop(error_man).
ok

内容概要:该论文深入研究了液压挖掘机动臂下降势能回收技术,旨在解决传统液压挖掘机能耗高的问题。提出了一种新型闭式回路势能回收系统,利用模糊PI自整定控制算法控制永磁无刷直流电动机,实现了变转速容积调速控制,消除了节流和溢流损失。通过建立数学模型和仿真模型,分析了不同负载下的系统性能,并开发了试验平台验证系统的高效性和节能效果。研究还涵盖了执行机构能量分布分析、系统元件参数匹配及电机控制性能优化,为液压挖掘机节能技术提供了理论和实践依据。此外,通过实验验证,该系统相比传统方案可降低28%的能耗,控制系统响应时间缩短40%,为工程机械的绿色化、智能化发展提供了关键技术支撑。 适合人群:从事工程机械设计、制造及维护的工程师和技术人员,以及对液压系统节能技术感兴趣的科研人员。 使用场景及目标:①理解液压挖掘机闭式回路动臂势能回收系统的原理和优势;②掌握模糊PI自整定控制算法的具体实现;③学习如何通过理论建模、仿真和实验验证来评估和优化液压系统的性能。 其他说明:此研究不仅提供了详细的理论分析和数学建模,还给出了具体的仿真代码和实验数据,便于读者在实际工作中进行参考和应用。研究结果表明,该系统不仅能显著提高能源利用效率,还能延长设备使用寿命,降低维护成本,具有重要的工程应用价值。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值