呃,在gen_event中有两个添加handler的方法

gen_event:add_handler/3
gen_event:add_sup_handler/3

一开始总是有些迷惑两者的区别,今天查看了gen_event源码,总算弄清两者的区别。

add_handler添加的只是把gen_event作为容器,仅仅在适当的时间调用模块的回调函数。(后面我描述为normal handler)

而add_sup_hander除了在适当的时间调用模块的回调函数以外,同时link到调用该函数的进程。(后面我描述为supervised handler)

首先看看在gen_event中描述handler的record

-record(handler, {module             :: atom(),id = false,state,supervised = false :: 'false' | pid()}).

supervised字段用来区分是那种类型的handler,

首先我们查看一下,添加两种类型的handler实际做了什么事。

%% server_add_handler(Handler, Args, MSL) -> {Ret, MSL'}.
%%   where MSL = [#handler{}]
%%   Ret goes to the top level MSL' is the new internal state of the
%%   event handlerserver_add_handler({Mod,Id}, Args, MSL) ->Handler = #handler{module = Mod,id = Id},server_add_handler(Mod, Handler, Args, MSL);
server_add_handler(Mod, Args, MSL) -> Handler = #handler{module = Mod},server_add_handler(Mod, Handler, Args, MSL).server_add_handler(Mod, Handler, Args, MSL) ->case catch Mod:init(Args) of{ok, State} ->{false, ok, [Handler#handler{state = State}|MSL]};{ok, State, hibernate} ->{true, ok, [Handler#handler{state = State}|MSL]};Other ->{false, Other, MSL}end.%% Set up a link to the supervising process.
%% (Ought to be unidirected links here, Erl5.0 !!)
%% NOTE: This link will not be removed then the
%% handler is removed in case another handler has
%% own link to this process.
server_add_sup_handler({Mod,Id}, Args, MSL, Parent) ->link(Parent),Handler = #handler{module = Mod,id = Id,supervised = Parent},server_add_handler(Mod, Handler, Args, MSL);
server_add_sup_handler(Mod, Args, MSL, Parent) -> link(Parent),Handler = #handler{module = Mod,supervised = Parent},server_add_handler(Mod, Handler, Args, MSL).

从上面的代码可以看到,如果添加的是normal handler,supervised保持为默认的'false',

如果为supervised handler,则存放调用改函数时候的进程id。

最后,都调用了Mod:init/1函数,将生成handler添加进handlers 列表中。

接下来,我们再看看当gen_event接受到'EXIT'消息时候,做的处理。

%% First terminate the supervised (if exists) handlers and
%% then inform other handlers.
%% We do not know if any handler really is interested but it
%% may be so !
handle_exit(From, Reason, MSL, SName) ->MSL1 = terminate_supervised(From, Reason, MSL, SName),{_,MSL2}=server_notify({'EXIT', From, Reason}, handle_info, MSL1, SName),MSL2.terminate_supervised(Pid, Reason, MSL, SName) ->F = fun(Ha) when Ha#handler.supervised =:= Pid ->do_terminate(Ha#handler.module,Ha,{stop,Reason},Ha#handler.state,{parent_terminated, {Pid,Reason}},SName,shutdown),false;(_) ->trueend,lists:filter(F, MSL).do_terminate(Mod, Handler, Args, State, LastIn, SName, Reason) ->Res = (catch Mod:terminate(Args, State)),report_terminate(Handler, Reason, Args, State, LastIn, SName, Res),Res.

因为在添加supervised  handler时候,我们link到了调用者进程。

所以当收到'EXIT'通知消息的时候,我们必须判断是否为supervised 进程的终止消息,如果是的话,需要删除handler列表中的该supervised handler。

同时调用Mod:terminate/2函数,并通知其他的handlers。

当停止gen_event时候:

terminate_server(Reason, Parent, MSL, ServerName) ->stop_handlers(MSL, ServerName),do_unlink(Parent, MSL),exit(Reason).%% unlink the supervisor process of all supervised handlers.
%% We do not want a handler supervisor to EXIT due to the
%% termination of the event manager (server).
%% Do not unlink Parent !
do_unlink(Parent, MSL) ->lists:foreach(fun(Handler) when Handler#handler.supervised =:= Parent ->true;(Handler) when is_pid(Handler#handler.supervised) ->unlink(Handler#handler.supervised),true;(_) ->trueend,MSL).

我们也需要判断supervised handler,对进程进行unlink,当gen_event进程结束时候,并不会强制supervisored handler进程结束。

而在下面两个函数调用时候:

gen_event:delete_handler/3
gen_event:swap_sup_handler/3

除了正常的逻辑,同时向supervisored handler的宿主进程发送{gen_event_EXIT,Handler,Reason},supervised handler进程可以依此消息来做出处理。。。

转载于:https://www.cnblogs.com/star-star/archive/2013/05/23/3095203.html

gen_event中的handler和supervised handler相关推荐

  1. 【Android 异步操作】Handler ( 主线程中的 Handler 与 Looper | Handler 原理简介 )

    文章目录 一.主线程中的 Handler 与 Looper 二.Handler 原理简介 一.主线程中的 Handler 与 Looper Android 系统中 , 点击图标启动一个应用进程 , 就 ...

  2. Android中的消息机制:Handler消息传递机制

    参考<疯狂android讲义>第2版3.5 P214 一.背景 出于性能优化考虑,Android的UI操作并不是线程安全的,这意味着如果有多个线程并发操作UI组件,可能导致线程安全问题.为 ...

  3. 【Android 异步操作】手写 Handler ( Handler 发送与处理消息 | Handler 初始化 | 完整 Handler 代码 )

    文章目录 一.Handler 发送与处理消息 ( 两大功能 ) 二.Handler 初始化 三.完整 Handler 代码 一.Handler 发送与处理消息 ( 两大功能 ) Handler 有两个 ...

  4. android handler内存,Android handler之内存泄露原因揭示

    关于handler机制大家可以看前面专题Android面试精选--再聊android Handler机制.今天我们要说的重点是 handler为什么会发生内存泄露? 我们先从源头说起,应用刚启动时,第 ...

  5. 85、android handler的警告Handler Class Should be Static or Leaks Occur

    转载:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2014/1106/1922.html 在使用Handler更新UI的时候,我是这样写 ...

  6. 安卓handler的用法,handler举例

    原帖跳转: link 一.Handler的定义: Handler主要接收子线程发送的数据, 并用此数据配合主线程更新UI,用来跟UI主线程交互用.比如可以用handler发送一个message,然后在 ...

  7. handler.post和handler.sendMessage的区别和联系

    现在大部分人都很熟悉handler这个东西了,我们常用handler的场景无非有两个: 1. 异步更新UI 2. 延时任务 但是我一直有一个困惑,就是handler.post(r)这个方法有什么独特的 ...

  8. Handler完全解读——Handler的使用

    个人博客:https://blog.N0tExpectErr0r.cn 小专栏:https://xiaozhuanlan.com/N0tExpectErr0r Handler完全解读--Handler ...

  9. 继承Handler还是实现Handler.Callback?

    Android的Handler提供了多种创建方式: package com.chanryma.demo;import android.os.Handler; import android.os.Mes ...

最新文章

  1. 中国队拿下口罩人脸识别世界第一!还将推出全球最大公开人脸数据集
  2. debugger markup language帮助文档(DML)
  3. Eclipse中的checkstyle插件
  4. 计算机网络【二】物理层基础知识
  5. C 怎么读取Cpp文件_python之调用C加速计算(一)
  6. 挖一挖产品经理的核心竞争力
  7. linux打开文件异常
  8. 9.卷1(套接字联网API)---基本SCTP套接字编程
  9. 【Scratch案例教学】scratch旋转风车 ​​​​scratch编程案例教学 scratch创意编程 少儿编程教案
  10. 【错误信息】Maximum call stack size exceeded
  11. 软件测试面试题目—接口测试面试题,梦寐以求的答案来了
  12. 非极大值抑制(Non-Maximum Suppression,NMS)
  13. mtk平台sensor分析一:alsps框架下的光距感驱动流程
  14. 情人节快乐(转)十五首最美爱情古诗词,伴你过一个温馨浪漫的情人节
  15. 运输小猫(斜率优化)
  16. FSA-Net学习笔记
  17. 多租户:防止意外创建可插拔数据库(PDB)- Lone-PDB
  18. 关于面向对象(OOB)的一些理解。主要是封装、继承、多态。
  19. C++仿照标准字符串类string,设计一个自己的字符串类String
  20. Markdown语法笔记

热门文章

  1. Huggingface及BERT代码介绍
  2. LARS 算法简介-机器学习
  3. The listener supports no services
  4. TVM编译机器学习到 WASM 和 WebGPU
  5. TensorRT 数据格式说明
  6. 每秒能捕捉万亿帧的相机
  7. YOLOV4各个创新功能模块技术分析(二)
  8. 半导体群聚、虚拟垂直、整合
  9. 2021年大数据Hive(三):手把手教你如何吃透Hive数据库和表操作(学会秒变数仓大佬)
  10. 第二个Python程序:if,for,while,输出乘法口诀表