erlang gen_event解析

基本概述

gen_event 是一个时间触发器的操作,支持异步消息处理和同步消息处理。通过调用gen_event:notify(M, Event) -> send(M, {notify, Event}) 发送数据信息,给已经注册到M模块的时间句柄发送信息。

基本功能模块

system信息

  • 处理系统信息system,通过sys模块的方法调用
  • 处理了基本的五个模块:system_code_change(模块变更的处理),system_continue(系统suspend之后的重新启动),system_get_state(获取进程的state数据),system_replace_state(系统替换state数据),system_terminate(系统关闭处理)

启动 gen_event 模块

  • 模块调用gen_event:start/start_link的方法启动进程
  • gen_event不支持模块回调,所有的消息处理都是在gen_event模块处理
  • 所有的gen_event模块不需要继承gen_evnet的行为

启动事件句柄

  • 此事件句柄必须满足gen_event的call_init接口,所以,此事件必须拥有gen_event的行为
  • gen_event的行为包括:init/1,handle_info/2,terminate/2,code_change/3(可以进行事件句柄的state结构变更),format_status/2(用于格式化的导出事件句柄的state数据) ,handle_call/2(执行事件的call同步操作),handle_event/2(事件的处理)这五个都需要存在
  • 通过add_handle(M,Handler, Args)添加handler处理或者add_sup_handler(M,Handler,Args)添加handler处理,并且将当前进程作为该handler事件的监督进程进行管理

通知事件句柄处理事件

  • 调用gen_event:notify(M,Msg) 通知注册在M模块下的事件句柄通过handle_event接口处理事件
  • 通过sync_notify/2函数同步的通知事件句柄通过handle_event接口处理事件
  • 通过call接口指定M模块下的Handler句柄处理Query事件,调用Handler模块的handle_call接口处理Query事件

事件句柄的切换

  • 提供两种模式,一种是swap_handler/3,将旧的handler数据替换为新的handler数据
  • swap_sup_handler/3,将旧的handler数据替换为新的handler数据,并且将新的handler最为当前进程的监督者,并且讲监督者进程link监控

停止事件

  • stop/1或者stop/3停止时间进程
  • system_terminate函数调用terminate_server函数关闭服务器
  • 调用各个handler的terminate函数退出
  • 将之前监控handler事件句柄的进程unlink掉(注意如果监督者是事件进程,则忽略)

其他实现功能

  • 关于指定模块句柄的state数据变更。调用方法:sys:change_code方法,会调用到gen_event的system_code_change,对指定模块进行state数据的变更;注意:进程必须是在suspend状态下才行。
  • 获取事件模块的state信息。调用sys:get_state()
  • 获取事件模块的状态信息。调用sys:get_status()
  • 进程挂起。如果事件handler的返回值是hibernate,则会把进程挂起,挂起后,会回调wake_hib,如果有其他事件进来,则会重新激活进程。
  • 监听handlers事件监督者挂掉 “ {"EXIT", From, Reason}" 事件会调用handle_exit/4函数关掉该监督者下的所有事件handler

一点项目相关

  • 概述1:游戏开发多年,用erlang开发游戏,每个玩家都创建一个进程,每个功能都存一个自己的进程字典,
  • 问题1:这样就会出现,一旦erlang的进程崩溃,只会导出state的数据,并不会导出进程字典的数据,给查问题带来了一定的难度。
  • 解决方案:如果都存在state上,则可以在奔溃发生时,找到原始的数据,进行查错。