Erlang OTP 设计原理.pdf.pdf_第1页
Erlang OTP 设计原理.pdf.pdf_第2页
Erlang OTP 设计原理.pdf.pdf_第3页
Erlang OTP 设计原理.pdf.pdf_第4页
Erlang OTP 设计原理.pdf.pdf_第5页
已阅读5页,还剩83页未读 继续免费阅读

Erlang OTP 设计原理.pdf.pdf.pdf 免费下载

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

erlang otp 设计原理 page 1 of 88 欢迎阅读 erlang otp 设计原理文档 原文 otp design principles 翻译 shiningray 文档整理 老天眷顾的孩纸 有任何问题请到 这里 留言 erlang otp 设计原理 page 2 of 88 目录 第一章 概述 7 1 监督树 7 2 行为 7 3 应用 11 4 发布 12 5 发布处理 12 第二章 gen server 行为 13 1 客户端 服务器端原理 13 2 例子 13 3 启动一个 gen server 14 4 同步调用 call 15 5 异步请求 cast 15 6 停止 16 7 在监督树中 16 8 独立 gen server 17 9 处理其他消息 17 第三章 gen fsm 行为 18 1 有限状态机 18 2 例子 18 3 启动一个 gen fsm 19 4 事件通知 20 5 超时 21 6 所有的状态事件 21 7 停止 22 8 在监督树中 22 9 独立的 gen fsm 22 erlang otp 设计原理 page 3 of 88 10 处理其他消息 23 第四章 gen event 行为 23 1 事件处理原理 23 2 例子 24 3 启动一个事件管理器 25 4 添加事件处理器 25 5 事件通知 26 6 删除事件处理器 26 7 停止 27 8 在监督树中 27 9 独立的事件管理器 27 第五章 supervisor 行为 28 1 监督原理 28 2 例子 28 3 重启策略 28 4 最大重启频率 29 5 子进程规格 30 6 启动一个督程 31 7 添加子进程 32 8 停止子进程 32 9 simple one for one 督程 32 10 停止 33 第六章 sys 与 proc lib 34 1 简单调试 34 2 特殊进程 35 3 例子 36 4 启动进程 38 erlang otp 设计原理 page 4 of 88 5 调试 39 6 处理系统消息 40 7 用户定义的行为 42 第七章 应用 44 1 应用的概念 44 2 应用回调模块 44 3 应用资源文件 45 4 目录结构 46 5 应用控制器 47 6 加载和卸载应用 47 7 启动和停止应用 48 8 配置应用 48 9 应用启动类型 50 第八章 被包含的应用 51 1 定义 51 2 指定被包含的应用 51 3 在启动过程中同步进程 52 第九章 分布式应用 54 1 定义 54 2 指定分布式应用 54 3 启动和停止分布式应用 55 4 故障转移 56 5 接管 57 第十章 发布 58 1 发布的概念 58 2 发布资源文件 58 3 生成启动脚本 59 erlang otp 设计原理 page 5 of 88 4 创建一个发布包 60 5 目录结构 61 6 无盘与只读客户端 62 第十一章 发布处理 64 1 发布处理原理 64 2 要求 65 3 分布式系统 65 4 发布处理指令 65 5 load module 66 6 update 66 7 add module 和 delete module 67 8 应用指令 67 9 apply 低级 68 10 restart new emulator 低级 68 11 应用升级文件 68 12 发布升级文件 70 13 安装一个发布 71 14 更新应用规格 74 第十二章 appup cookbook 76 1 变更功能模块 76 2 变更驻留模块 76 3 更改回调模块 76 4 变更内部状态 77 5 模块依赖性 78 6 变更特殊进程的代码 79 7 变更督程 80 8 变更属性 80 9 变更子进程规格 81 erlang otp 设计原理 page 6 of 88 10 添加和删除子进程 81 11 添加或删除模块 82 12 启动或终止进程 82 13 添加或移除应用 82 14 重启应用 83 15 变更应用规格 83 16 变更应用配置 83 17 变更被包含的应用 83 18 应用重启 84 19 督程变更 85 20 变更非 erlang 代码 86 21 模拟器重启 87 erlang otp 设计原理 page 7 of 88 第一章 概述 本 otp 设计原则是针对如何根据进程 模块和目录组织 erlang 代码的一系列原则 1 监督树 在 erlang otp 中有一个基本概念叫监督树 这是一种建立在督程与佣程思想上的进程结 构化模型 佣程佣程 worker 是进行计算的进程 也就是说 它们进行实际的工作 督程督程 supervisor 是监视工作者行为的进程 监督者可以重启工作者如果出现了什 么问题 监督树监督树是一种将代码分成监督者和工作者的层次安排 这样才能设计和编写可容错的 软件 上图中 方框提供监督 圆圈是工作者 2 行为 在监督树中 很多进程有着相似结构 遵循类似的模式 例如 督程的结构都很相似 他们之间的唯一区别在于所监督的子进程 此外 很多佣程都是处于服务器 客户端关系中 的服务器 有限状态机或者诸如错误日志这样的事件处理器 行为是对这些常见模式的形式化 其思想是将一个进程的代码划分为一个通用的部分 行 为模块 和一个特定的部分 回调模块 行为模块是 erlang otp 的一部分 要实现一个督程 用户只需要实现回调模块 导出预 定义集合中的函数 回调函数 erlang otp 设计原理 page 8 of 88 一个例子可以用来说明代码是如何被划分成为通用和特定部分的 考虑下面的代码 普 通 erlang 编写 一个简单的服务器 用于保持跟踪一些 频道 其他进程可以通过调用 alloc 0 和 free 1 函数来相应地分配和释放一个频道 modulemodule ch1 exportexport start 0 exportexport alloc 0 free 1 exportexport init 0 start spawn ch1 init alloc ch1 self alloc receivereceive ch1 res res endend free ch ch1 free ch ok init register ch1 self chs channels loop chs loop chs receivereceive from alloc ch chs2 alloc chs from ch1 ch loop chs2 free ch chs2 free ch chs loop chs2 endend 服务器的代码可以重写为一个通用的部分 server erl modulemodule server exportexport start 1 exportexport call 2 cast 2 erlang otp 设计原理 page 9 of 88 exportexport init 1 start mod spawn server init mod call name req name call self req receivereceive name res res endend cast name req name cast req ok init mod register mod self state mod init loop mod state loop mod state receivereceive call from req res state2 mod handle call req state from mod res loop mod state2 cast req state2 mod handle cast req state loop mod state2 endend 还有一个回调模块 ch2 erl modulemodule ch2 exportexport start 0 exportexport alloc 0 free 1 exportexport init 0 handle call 2 handle cast 2 start serverserver start ch2 alloc serverserver call ch2 alloc erlang otp 设计原理 page 10 of 88 free ch serverserver cast ch2 free ch init channels handle call alloc chs alloc chs ch chs2 handle cast free ch chs free ch chs chs2 注意以下几点 server 中的代码可以被重用于建立很多不同的服务器端 服务器的名字 这个例子中为原子 ch2 对于客户端函数的用户而言是隐藏 的 这意味无须影响客户端就可以改变名字 协议 发给服务器和从服务器接收到的消息 也是隐藏的 这是很好的编程实践 让我 们可以在不改变接口函数的代码的情况下改变协议 我们可以扩展服务器 server 的功能 而不用改变 ch2 或任何其它的回调模块 在上面的 ch1 erl 和 ch2 erl 中 channels 0 alloc 1 free 2 的实现被特 意省略了 因为和这个例子无关 为了完整起见 下面会给出这些函数的一种写法 注意这 只是个例子 实际的实现必须能够处理一些特殊情况 如频道用光无法分配等 channels allocated free listslists seq 1 100 alloc allocated h t free h h allocated t free ch alloc free channels casecase listslists member ch alloc ofof true listslists delete ch alloc ch free false channels endend erlang otp 设计原理 page 11 of 88 不用行为来写的代码可能会更快些 但是所提高的效率是要付出通用性上的代价 对系 统中以一致的方式管理所有应用的能力是非常重要的 使用行为也可以使得由其他程序员所写的代码更容易阅读和理解 专门的编程结构 可 能会更高效 但是往往更加难于理解 模块 server 对应的是极大简化了的 erlang otp 中的 gen server 行为 标准 erlang otp 行为有 gen servergen server 用于实现 c s 结构中的服务端 gen fsmgen fsm 用于实现有限状态机 gen eventgen event 用于实现事件处理功能 supervisorsupervisor 用于实现监督树中的督程 编译器看到模块属性 behaviour behaviour 后会提出缺少的回调函数的警告 例 如 modulemodule chs3 behaviourbehaviour gen server 3 c chs3 chs3 erlerl 10 warning undefined call back function handle call 3 ok chs3 3 应用 erlang otp 还提供了一系列组件 每个实现一些特定的功能 这种组件用 erlang otp 的 术语来说 叫做应用 application erlang otp 应用的例子有 mnesia 具备了所有数据 库服务编程所需的东西 debugger 用于调试 erlang 程序 基于 erlang otp 的最精简的系 统由应用 kernel 和 stdlib 组成 erlang otp 设计原理 page 12 of 88 使用标准行为可以很简单地将一个带有进程的应用程序实现为监督树 如何编写应用将在 应用应用 一节进行描述 4 发布 一个发布 release 是一个由 erlang otp 应用的子集和一系列用户定义的应用组成的 完整系统 如何编写应用将在发布发布 releases 一节中进行描述 5 发布处理 发布处理是在一个 可能 运行中的系统上 对一个发布的不同版本之间进行升级和降 级的操作 在 发布处理发布处理 一节中会描述怎么做 erlang otp 设计原理 page 13 of 88 第二章 gen servergen server 行为 本章要与 gen server 3 结合起来阅读 它详细描述了所有的接口函数和回调函数 1 客户端 服务器端原理 客户端 服务器端 c s 模型的特点是 一个中央服务器和任意数量的客户端 c s 模 型通常用于资源管理操作 其中一些不同的客户端要共享一个公共资源 服务器负责管理这 些资源 2 例子 在概述中 已经有一个用普通 erlang 方式写的简单服务器 这个服务器可以用 gen server 进行重写 结果产生这个回调模块 modulemodule ch3 behaviourbehaviour gen server exportexport start link 0 exportexport alloc 0 free 1 exportexport init 1 handle call 3 handle cast 2 start link gen servergen server start link local ch3 ch3 erlang otp 设计原理 page 14 of 88 alloc gen servergen server call ch3 alloc free ch gen servergen server cast ch3 free ch init args ok channels handle call alloc from chs ch chs2 alloc chs reply ch chs2 handle cast free ch chs chs2 free ch chs noreply chs2 在下一节中会解释这段代码 3 启动一个 gen server 在前一节中的代码 可以通过 ch3 start link 来启动这个 gen server start link gen servergen server start link local ch3 ch3 ok pid start link 调用了函数 gen server start link 4 这个函数产生了一个新进程一个 gen server 并联接到其上 第第 1 1 个参数个参数 local ch3 指定了名称 在这种情况下 gen srever 将在本地被注 册为 ch3 如果忽略名称 那么这个 gen server 就不会被注册了 这时就必须使 用其 pid 名称也可以以 global name 的形式给出 这种情况下 gen server 则 会使用 global register name 2 来进行注册 第第 2 2 个参数个参数 ch3 则是回调模块的名字 也就是回调函数所放的那个模块 在这 里 接口函数 start link alloc 和 free 和回调函数 init handle call 和 handle cast 一般来说这是好的编程实践 将代表同一个进程的代码包含在同 一个模块中 第第 3 3 个参数个参数 这个值将被原封不动传递给回调函数 init 在这里 init 无须任 何输入数据将忽略这个参数 erlang otp 设计原理 page 15 of 88 第第 4 4 个参数个参数 是参数的列表 具体的参数请查看 gen server 3 在注册名称成功后 新的 gen server 进程会调用回调函数 ch3 init init 返回 ok state 其中 state 是 gen server 的内部状态 在这里 状态就是可用的频道 init args ok channels 注意 gen server start link 是同步的 只有等到 gen server 被完全初始化并准备接 受请求之后才会返回 如果 gen server 是某棵监督树的一部分 即 gen server 是由一个督程启动的 那么必 须使用 gen server start link 还有另外一个函数 gen server start 用于启动一个独立 的 gen server 即不是某棵监督树一部分的一个 gen server 4 同步调用 call 同步请求 alloc 是使用 gen server call 2 实现的 alloc gen servergen server call ch3 alloc ch3 是 gen server 的名字 必须和启动时的名字一样 alloc 是实际的请求 请求以消息的形式发送给这个 gen server 当收到了请求之后 gen server 调用 handle call request from state 它应返回一个元组 reply reply state1 reply 是需要回馈给客户端的答复 同时 state1 是 gen server 的状态的新值 handle call alloc from chs ch chs2 alloc chs reply ch chs2 在这里 应答是分配了的频道 ch 然后 gen server 将等待新的请求 并且现在保持了一个最新的可用 频道的列表 5 异步请求 cast 异步请求 free ch 使用 gen server cast 2 实现 free ch gengen server server cast ch3 free chr erlang otp 设计原理 page 16 of 88 ch3 是 gen server 的名称 free ch 是实际的请求 请求被装在一个消息中发给 gen server 的 cast 这调用了 free 然后返回了 ok 当 gen server 收到请求之后 它会调用 handle cast request stats 会返回一个 元组 noreply state1 state1 是 gen server 状态的新值 handle cast free ch chs chs2 free ch chs noreply chs2 在这里 新的状态便是更新过的可用频道列表 chs2 gen server 现在又可以接受新的 请求了 6 停止 7 在监督树中 若 gen server 是某个监督树的一部分 则无需停止函数 它的督程会自动终止它 它的 具体做法由督程中设置的 关闭策略 定义 如果在终止之前需要进行一些清理工作 那么关闭策略必须是一个超时值 同时 gen server 必须在 init 函数中设置为捕获退出信号 当 gen server 被要求关闭时 它就 会调用回调函数 terminate shutdown state init args process flag trap exit true ok state terminate shutdown state code for cleaning up here ok erlang otp 设计原理 page 17 of 88 8 独立 gen server 如果 gen server 并非某个监督树的一部分 那么可以用一个停止函数 例如 export stop 0 stop gen servergen server cast ch3 stop handle cast stop state stop normal state handle cast free ch state terminate normal state ok 回调函数处理 stop 请求并返回一个元组 stop normal state1 其中 normal 表 示这是一个正常的终止 state1 是 gen server 状态的新值 这会引发 gen server 调用 terminate normal state1 来优雅地终止 9 处理其他消息 如果要想 gen server 还能处理请求之外的消息 必须实现回调函数 handle info info state 来处理他们 例如 如果 gen server 联结到其它进程 非督程 上并捕获退出信 号 那么其它的消息就有退出消息 handle info exit pid reason state code to handle exits here noreply state1 erlang otp 设计原理 page 18 of 88 第三章 gen fsmgen fsm 行为 本章应该结合 gen fsm 3 来阅读 其中面有所有接口函数和回调函数的详细说明 1 有限状态机 一个有限状态机 fsm 可以用一个关系式来描述 state s x event e actions a state s 这些关系解释如下 如果我们处在状态 s 并且事件 e 发生了 那么 我们需要执行动作 a 并且转变 到状态 s 对于一个用 gen fsm 行为实现的 fsm 来说 状态转换规则被写为符合如下约定的一系列 erlang 函数 statename event statedata 这里放动作的代码 next state statename statedata 2 例子 一个带有密码锁的门可以被看作一个 fsm 初始状态下 门是锁着的 一个人无论何时按 下一个按钮都会产生一个事件 取决于之前哪些按钮被按下 当前序列可能是正确的 不完 整 或者错误的 如果是正确的 那么门会打开 30 秒 30000ms 如果是不完整的 那么等待按下另一个 按钮 如果是错误的 那么我们重来 等待新的按钮序列 使用 gen fsm 实现的密码锁可以得到以下回调模块 modulemodule code lock behaviourbehaviour gen fsm exportexport start link 1 exportexport button 1 exportexport init 1 locked 2 open 2 start link code gen fsmgen fsm start link local code lock code lock code erlang otp 设计原理 page 19 of 88 button digit gen fsmgen fsm send event code lock button digit init code ok locked code locked button digit sofar code casecase digit sofar ofof code do unlock next state open code 3000 incomplete whenwhen length incomplete next state locked incomplete code wrong next state locked code endend open timeout state do lock next state locked state 该代码将会在下一节中进行解释 3 启动一个 gen fsm 在上一节的例子中 该 gen fsm 是通过调用 code lock start link code 来启动的 start link code gen fsmgen fsm start link local code lock code lock code start link 调用函数 gen fsm start link 4 该函数产生并连接到一个新的 gen fsm 进程 第第 1 1 个参数个参数 local code lock 指明了名字 在这里 gen fsm 会在本地注册为 code lock 如果名字被省略了 那么将不会注册 gen fsm 这样就必须使用它的 pid 名字也可以这样写 global name 这样 gen fsm 就是使用 global register name 2 来注册了 第第 2 2 个参数个参数 code lock 是回调模块的名字 也就是回调函数所位于的模块 在这个 例子里面 接口函数 start link 和 button 是位于和回调函数 init locked 和 erlang otp 设计原理 page 20 of 88 open 相同的模块中 这一般是较好的编程实践 让一个进程对应的代码包含在一个 模块里面 第第 3 3 个参数个参数 code 是一个值 将被原封不动传递给回调函数 init 这里 init 得 到锁的正确代码做为内部数据 第第 4 4 个参数个参数 是一个选项的列表 参见 gen fsm 3 来找到可用的选项 如果名称注册成功 新的 gen fsm 进程会调用回调函数 code lock init code 这个函 数要返回 ok statename statedata 其中 statename 是 gen fsm 初始状态的名字 在 这个例子里面是 locked 假设门一开始是锁着的 statedata 是 gen fsm 的内部状态 对 于 gen fsm 来说 内部状态一般是指 状态数据 state data 以区别于状态机的状态 在这个例子里面 状态数据 state data 是到目前为止的按钮的顺序 开始的时候为空 和锁的正确密码顺序 init code ok locked code 注意 gen fsm start link 是同步的 它只有到 gen fsm 已经完成初始化并且可以接收通 知的时候才返回 如果 gen fsm 是一个监毒树的一部分的话 即由督程启动的 必须使用 gen fsm start link 有另外一个函数 gen fsm start 来启动一个独立的 gen fsm 即 gen fsm 不属于监督树的一部分 4 事件通知 通知密码锁一个按钮被按下的事件是使用 gen fsm send event 2 来实现的 button digit gen fsmgen fsm send event code lock button digit code lock 是 gen fsm 的名字并且必须与启动时候所使用的名字一致 button digit 是实际的事件 事件被做为消息发送给 gen fsm 当 gen fsm 收到这个事件的时候 就会调用 statename event statedata 该函数需要返回一个元组 next state statename1 statedata1 statename 是当前状态的名字 而 statename1 是要转到的下一个状态的名 字 statedata1 是 gen fsm 的状态数据的新的值 locked button digit sofar code casecase digit sofar ofof erlang otp 设计原理 page 21 of 88 code do unlock next state open code 30000 incomplete whenwhen length incomplete next state locked incomplete code wrong next state locked code endend open timeout state do lock next state locked state 如果门是锁着的 且按下了按钮 那么 到目前位置所有的按钮序列就会与密码锁正确 的密码进行比较 然后根据比较的结果 要么门是解锁了 gen fsm 进入打开的状态 open 或者是仍然是处于锁着的状态 locked 5 超时 当一个正确的按钮顺序被按下之后 门会被打开 下面的元组就会从函数 locked 2 返 回 next state open code 3000 30000 是一个以毫秒为单位的超时值 30000ms 也就是 30 秒后 就会发生一个超时 然后 statename timeout statedata 就会被调用 在这个例子里面 当门处于状态 open 打开 30 秒后就会发生超时 然后门又会被锁上 open timeout state do lock next state locked state 6 所有的状态事件 有时候 在 gen fsm 的任何状态都有可能有事件到达 除了可以用 gen fsm send event 2 发送消息 并为每一个状态函数写一个子句来处理事件之外 还可以 通过 gen fsm send all state event 2 来发送消息 并用 module handle event 3 来处 理 modulemodule code lock erlang otp 设计原理 page 22 of 88 exportexport stop 0 stop gen fsmgen fsm send all state event code lock stop handle event stop statename statedata stop normal statedata 7 停止 8 在监督树中 如果 gen fsm 是监督树的一部分 那么不需要停止函数 它的督程会自动停止它 具体 如何进行是通过督程中的关闭策略集来定义 如果需要在终止前先进行清除操作 那么关闭策略必须是一个超时值 并且 gen fsm 必 须在 init 函数里面设置成捕捉退出信号 当被要求关闭时 gen fsm 会调用回调函数 terminate shutdown statename statedata init args process flag trap exit true ok statename statedata terminate shutdown statename statedata code for cleaning up here ok 9 独立的 gen fsm 如果 gen fsm 不是监督树的一部分 那么一个停止函数是有用的 例如 erlang otp 设计原理 page 23 of 88 exportexport stop 0 stop gen fsmgen fsm send all state event code lock stop handle event stop statename statedata stop normal statedata terminate normal statename statedata ok 处理 stop 事件的回调函数返回一个元组 stop normal statedata1 这里的 normal 指明了这是一个正常的终止 同时 statedata1 是 gen fsm 状态数据的新值 这会使 gen fsm 去调用 terminate normal statename statedata1 然后优雅的终止 10 处理其他消息 如果 gen fsm 需要接收事件之外的消息 那么必须实现回调函数 handle info info statename statedata 来处理这些消息 其他的消息比如退出消息 如果 gen fsm 是联接 到其他的进程 非督程 的 并且需要捕获退出信号 handle info exit pid reason statename statedata code to handle exits here next state statename1 statedata1 第四章 gen eventgen event 行为 本章应和 gen event 3 相结合阅读 它包含了所有接口函数和回调函数的详细说明 1 事件处理原理 在 otp 中 事件管理器 事件管理器 是一个命名对象 可以给其发送事件 一个 事 件 event 可以是诸如一个错误 一个警报或者是某种应被记录的信息 erlang otp 设计原理 page 24 of 88 在事件管理器中 可以安装零个 一个或者多个 事件处理器 事件处理器 当事件管 理器被通知有一个事件时 所有安装了的事件处理器都会来处理该事件 例如 一个处理错 误的事件管理器可以默认安装了一个将错误消息打印到终端的处理器 如果在某个特定期 间 错误消息也要被保存到一个文件中 那么用户可以添加另外一个做这个事情的事件处理 器 当不再需要记录到文件时 该事件处理器就会被删除 一个事件管理器实现为一个进程 而每个事件处理器则实现为一个回调模块 事件管理器本质上是在维护一个 module state 对的列表 其中每个 module 是一个 事件处理器 state 是事件处理器的内部状态 2 例子 将错误消息输出到终端的事件处理器的回调模块可以这样写 modulemodule terminal logger behaviourbehaviour gen event exportexport init 1 handle event 2 terminate 2 init args ok handle event errormsg state ioio format error p n errormsg ok state terminate args state ok 将错误消息写入到文件的事件处理器的回调模块可以是 modulemodule file logger behaviourbehaviour gen event exportexport init 1 handle event 2 terminate 2 init file ok fd filefile open file read ok fd erlang otp 设计原理 page 25 of 88 handle event errormsg fd ioio format fd error p n errormsg ok fd terminate args fd filefile close fd 这些代码将在下一节中解释 3 启动一个事件管理器 要启动上面例子中描述的处理错误的事件管理器 可以调用如下方法 gen eventgen event start link local error man 这个方法生产一个新的事件管理器进程并连接它 参数 local error man 指定了名字 在这里 事件管理器将在本地注册为 error man 如果名称被忽略 那么就不会注册事件管理器 这时就必须使用它的 pid 名称也可以以 global name 的形式给出 这种情况下则会使用 global register name 2 来注册事件管 理器 如果事件管理器是监督树的一部分 即由一个督程启动的 那么必须使用 gen event start link 启动 还有另外一个函数 gen event start 用于启动一个独立的事 件管理器 即 不属于任何监督树的事件管理器 4 添加事件处理器 以下例子使用了一个命令行演示了如何启动事件管理器并添加一个事件处理器 1 gen eventgen event start local error man ok 2 gen eventgen event add handler error man terminal logger ok 这函数给注册为 error man 的事件管理器发送了一个消息 告诉它要添加事件处理器 terminal logger 这个事件管理器会调用回调函数 terminal logger init 其中参 数 是传给 add handler 的第三个参数 init 要返回 ok state 其中 state 是事件 处理器的内部状态 erlang otp 设计原理 page 26 of 88 init args ok 这里 init 无须任何输入数据并忽略了它的参数 同样 对于 terminal logger 来说 内部状态也是用不到的 对于 file logger 来说 内部状态用于保存打开的文件描述符 init args ok fd filefile open file read ok fd 5 事件通知 3 gen eventgen event notify error man no reply error no reply ok error man 是事件管理器的名字 no reply 是事件 事件被作为一个消息发送给事件管理器 当收到了这个事件以后 事件管理器为每个安 装了的事件处理器按照他们添加的顺序调用 handle event event state 函数要返回一 个元组 ok state1 其中 state1 是事件处理器的状态的新值 在 terminal logger 中 handle event errormsg state ioio format error p n errormsg ok state handle event errormsg fd ioio format fd error p n errormsg ok fd 6 删除事件处理器 4 gen eventgen event delete handler error man terminal logger ok 这函数给注册为 error man 的事件管理器发送了一个消息 告诉它要删除处理器 terminal logger 事件管理器会调用回调函数 terminal logger terminate 其中参 erlang otp 设计原理 page 27 of 88 数 是传给 delete handler 的第三个参数 terminate 应该和 init 相反 进行必要的清 理工作 它的返回值会被忽略 对于 terminal logger 无须任何清理 terminate args state ok 对于 file logger 在 init 中打开的文件描述符需要被关闭 terminate args fd filefile close fd 7 停止 当停止事件管理器时 会通过调用 terminate 2 让每个事件处理器都有机会进行清除工 作 与删除处理器的方法一样 8 在监督树中 如果事件管理器是监督树的一部分 那无须停止函数 它的督程会自动终止它 具体如 何进行是通过督程中的关闭策略集来定义 9 独立的事件管理器 要停止一个事件管理器也可以调用 gen eventgen event stop error man ok erlang otp 设计原理 page 28 of 88 第五章 supervisorsupervisor 行为 本节应该与 supervisor 3 相结合阅读 其中有所有的督程行为的细节 1 监督原理 督程负责启动 停止和监视它的子进程 督程的基本思想是它要保持它的子进程有效 必要的时候可以重启他们 要启动和监视的子进程由一个 子进程规格 的列表来指定 子进程按照在这个列表中的 顺序启动 并且按照相反的顺序终止 2 例子 启动来自 gen servergen server 一章一章 的服务器的督程的回调模块可以是 modulemodule ch sup behaviourbehaviour supervisor exportexport start link 0 exportexport init 1 start link supervisorsupervisor start link ch sup init args ok one for one 1 60 ch3 ch3 start link permanent brutal kill worker ch3 one for one 是 重启策略 1 和 60 定义了 最大重启频率 元组 ch3 是 子进程规格 3 重启策略 1 1 one for oneone for one 如果一个子进程终止了 仅该进程被重启 erlang otp 设计原理 page 29 of 88 2 2 one for allone for all 如果一个子进程终止了 那么所有其他的子进程都被终止然后 所有的子进程都被 重启 包括原来被终止的那个 3 3 rest for onerest for one 如果一个子进程终止了 那么后面的子进程 即在启动顺序上在这个终止了的进程 后面的子进程 都被终止 然后该终止的进程和后面的子进程都被重启 4 最大重启频率 督程有一个内置的机制可以限制在给定时间间隔内可以发生的重启次数 它由两个参数 maxr 和 maxt 的值决定 这两个参数在由回调函数 init 返回的启动规格中 init ok restartstrategy maxr maxt childspec 如果在最近的 maxt 秒内发生的重启次数超过了 maxr 次 那么督程会终止所有的子进 程 然后结束自己 当督程终止了 那么更高一级的督程会采取一些措施 要么是重启终止了的督程 要么 终止自己 erlang otp 设计原理 page 30 of 88 这种重启机制的目的是防止出现一个进程反复因为同一个原因死掉又只知道反复重启的 情况 5 子进程规格 id startfunc restart shutdown type modules id term startfunc m f a m f atom a term restart permanent transient temporary shutdown brutal kill integer 0 infinity type worker supervisor modules module dynamic module atom idid 是督程内部用于标识子进程规范的名称 startfuncstartfunc 定义了用于启动子进程的很难书调用 它是一个模块 函数 参数的元组 与 apply m f a 用的一样 restartrestart 定义了一个被终止的子进程要在何时被重启 perpermanentmanent 子进程总会被重启 temporarytemporary 子进程从不会被重启 transienttransient 子进程只有当其被异常终止时才会被重启 即 退出理由不是 normal shutdownshutdown 定义了一个子进程应如何被终止 brutal kill 表示子进程应使用 exit child kill 进行无条件终止 一个整数超时值表示督程先通过调用 exit child shutdown 告诉子进程要终止 了 然后等待其返回退出信号 如果在指定的事件内没有接受到任何退出信号 那么 使用 exit child kill 无条件终止子进程 如果子进程是另外一个督程 那么应该设置为 infinity 以给予子树足够的时间关 闭 typ

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论