erlang四大behaviour之四-supervisor

http://www.cnblogs.com/puputu/articles/1689621.html
1. 监督规则

一个监督者负责启动、停止、监控他的子进程。监督者的一个基本概念就是当必要的时候重启子进程保证它们的存活

哪个子进程要重启和被监控是由一个子规程列表决定的,子进程按照列表中指定的顺序启动,并按相反的顺序终止

2. 实例

监督者的回调模块

-module(ch_sup).
 -behaviour(supervisor).
 -export([start_link/0]).
 -export([init/1]).
 start_link() ->
supervisor: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. 重启策略

one_for_one

假如一个进程终止了,仅仅这个进程会被重启

one_for_all

假如一个进程停止了,所有其他子进程也要被停止,然后所有子进程,包括这个引发停止的子进程都被重启

rest_for_one

假如一个进程停止了,它后面的子进程,也就是以启动顺序来说这个被终止的进程后面的子进程都将被停止,然后他们又被启动。

4. 最大启动频率

监督者有一个内建机制限制在给定的时间间隔里的重启次数,这由子进程启动规程中的两个参数值决定,MaxR和MaxT,它们定义在回调函数init中

init(...) ->
 {ok, {{RestartStrategy, MaxR, MaxT},
   [ChildSpec, ...]}}.

如果在时间MaxT里重启次数大于MaxR ,监督者进程就停止它所有子进程,然后再终止自己。

当监督者进程终止了,那么更高级别的监督者要采取些动作,它或者重启被终止的监督者或者停止自己

这个重启机制的目的是预防一个进程因某种原因频繁的终止,然后简单的重启。

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()

Id


用来内部标识子规范


StartFunc


是启动子进程时调用的函数,它将成为对supervisor:start_link, gen_server:start_link, gen_fsm:start_link or gen_event:start_link的调用


Restart


标识一个进程终止后将怎样重启,一个permanent 进程总会被重启;一个temporary 进程从不会被重启;一个transient 进程仅仅当是不正常的被终止后才重启,例如非normal得退出原因


Shutdown


定义一个进程将怎样被终止,brutal_kill意味着子进程被exit(Child, kill)无条件的终止;一个整数值的超时时间意味着监督者告诉子进程通过调用exit(Child, shutdown)而被终止,然后等待一个返回的退出信号,假如在指定的时间里没有收到退出信号,那么子进程用exit(Child, kill)被无条件终止。


Type


指定子进程是supervisor还是worker


Modules


是有一个元素的列表[Module],假如子进程是supervisor、gen_server 或 gen_fsm,那么Module 是回调模块的名称;假如子进程是gen_event,那么Modules 应该是dynamic

例如:子规范用于启动一个服务器ch3

{ch3, {ch3, start_link, []}, permanent, brutal_kill, worker, [ch3]}

子规范用于启动一个事件管理器

{error_man, {gen_event, start_link, [{local, error_man}]}, permanent, 5000, worker, dynamic}

监督者然后根据子规程启动所有子进程,这个例子中是一个子进程ch3

6. 启动supervisor

像这样

start_link() ->
 supervisor:start_link(ch_sup, []).

启动

监督者进程调用init

init(_Args) ->
{ok, {{one_for_one, 1, 60},
   [{ch3, {ch3, start_link, []},
      permanent, brutal_kill, worker, [ch3]}]}}.

并期待init返回{ok, StartSpec}

注意supervisor:start_link是同步的,它一直等到所有子进程都启动了才返回

7. 添加子进程

除静态监控树外,我们也可以通过supervisor:start_child(Sup, ChildSpec)向监督者动态添加子进程,Sup 是监督者的pid或名称,ChildSpec 是一个子规范。子进程用start_child/2来添加。注意:假如监督者死掉后重启,那么所有动态添加的子进程都不复存在

8. 停止子进程

任何静态动态添加的子进程都可以用supervisor:terminate_child(Sup, Id)来停止。一个停止子进程规范可以用supervisor:delete_child(Sup, Id)来删除。Sup是监督者的pid或名称,Id是子规范的id

9. Simple-One-For-One

监督者的simple_one_for_one启动策略是one_for_one的简版,所有子进程都是同一进程实例而被动态添加,下面是一个simple_one_for_one监督者的实例

-module(simple_sup).
-behaviour(supervisor).
-export([start_link/0]).
-export([init/1]).
start_link() ->    supervisor:start_link(simple_sup, []).
init(_Args) ->
   {ok, {{simple_one_for_one, 0, 1},
       [{call, {call, start_link, []},
           temporary, brutal_kill, worker, [call]}]}}.

当启动时,监督者不启动任何子进程,取而代之的是所有子进程都通过调用supervisor:start_child(Sup, List)来动态添加,Sup 是监督者的pid或名称,List 是添加给子规范中指定参数列表term列表,如果启动函数是{M, F, A}这种形式,那么子进程通过调用apply(M, F, A++List)而被启动

例如,给上面的例子添加一个子进程

supervisor:start_child(Pid, [id1])

那么子进程通过调用apply(call, start_link, []++[id1])而被启动,实际上就是call:start_link(id1)

10. 停止

因为监控者是监控树的一部分,它自动被他的监督者停止,根据相应规范,它反序停止它的所有子进程,然后终止自己

至此,四种behavour已经全部翻译完了,熟练应用他们是你构建高扩展、高容错、高并发应用的基础,努力吧!

时间: 2024-09-29 21:13:31

erlang四大behaviour之四-supervisor的相关文章

erlang四大behaviour之二-gen_fsm

来源:http://www.cnblogs.com/puputu/articles/1701012.html 今天介绍erlang的一个非常重要的behaviour,就是gen_fsm-有限状态机,有限状态机的作用非常之多,比如文本解析,模式匹配.游戏逻辑等等方面的处理都是它的强项,所以这个behaviour非常之重要 1. 有限状态机 有限状态机可以用下面这个公式来表达 State(S) x Event(E) -> Actions(A), State(S') 表示的就是在S状态时如果有事件E发

erlang四大behaviour之三-gen_event

来源:http://www.cnblogs.com/puputu/articles/1689623.html 1. 事件处理规则 在OTP中,事件管理器是一个事件可以发送到的命名对象,一个事件可以是一个错误.一个警告.或者一些要写入日志的信息 在事件管理器中,有0个.一个或者多个事件处理器被安装,当事件管理器被一个事件通知时,这个事件将被安装在事件管理器中的事件处理器处理, 事件管理器用一个进程实现,事件处理器用回调模块实现.事件管理器本质上维护一个{Module, State}列表,每一个Mo

Erlang OTP学习:supervisor [转]

转自: http://diaocow.iteye.com/blog/1762895 今天细致的看了下supervisor,现在做个总结: 其中,方块代表supervisor process,它的功能很简单,就负责看管它下面的“小弟”(child processes) 并且在必要的时候对某个child process执行restart或者terminate操作:而圆形就代表worker process,它才是真正负责干活的process:特别注意,supervisor process 监控的不一定

9、四大组件之四-Broadcast Receiver

课程目标: 了解Android消息机制 掌握Broadcast发送消息的两种类型 掌握BroadcastReceiver接收消息的编程 重点难点: sendOrderedBroadcast()的理解 考核目标: 说说Android中发送的两种广播分别是?以及他们的区别? 编写BroadcastReciever时候的注意事项 ? 一.Broadcast Reveiver作用及为何要引入? 用来接收系统及自定义消息的. 在系统内通知和判定执行状态 1,系统执行状态:开机了,TF卡插拔了,准备关机了,

启动erlang/OTP里面的Web服务器(application INETS启动过程代码分析)

上两篇分别用两种方式启动了inets中的httpd,其实本质一样的:下面简单分析一下过程,函数粒度的介绍. 1,下面是application inets的代码目录,虽然ftp.tftp.http_client.http_lib.http_server.inets_app在这目录中并列,其实inets_app扮演顶层控制角色: 只有inets_app是一个application,而其他都是module---application的一部分并且需要application启动和管理. [[email p

《逐梦旅程 WINDOWS游戏编程之从零开始》笔记7——四大变换

第13章 世界变换,取景变换,投影变换,视口变换 在Direct3D中,如果为进行任何空间坐标变换而直接绘图的话,图形将始终处于应用程序窗口的中心位置,默认这个位置就成为世界坐标系的原点(0,0,0).而且我们也不能改变观察图形的视角方向.默认情况下的观察方向是世界坐标系的z轴正向方向. 世界变换运算是为了能在世界空间中的指定位置来绘制图形 取景变换运算是为了以不同的视角观察图形 投影变换为了将相对较远的图形投影到同一个平面上并体现出"近大远小"的真实视觉效果 视口变换是为了控制显示图

关于erlang打包升级相关文档汇总

如果你需要了解erlang的打包升级,请参考一下文档. System PrinciplesUser's Guide:一篇关于erlang创建目标系统和升级系统相关的官方文档. http://www.erlang.org/doc/system_principles/system_principles.html 中文翻译:http://blog.sina.com.cn/s/blog_96b8a154010128dq.html sasl application是关于erlang打包升级的库 http:

韩顺平循序渐进学java 第12讲 多态

12.1 多态-四大特征之四 12.1.1 概念 所谓多态,就是指一个引用(类型)在不同情况下的多种状态. 可以这样理解:多态是指通过指向父类的指针,来调用在不同子类中实现的方法. 12.1.2 注意事项 在讲解多态的时候,我们注意到这样一个现象-类型的转换. 1.java允许父类的引用变量引用它的子类的实例(对象) Animal animal=new Cat(); 2.关于类型转换还有一些细节要求,比如子类能不能转换成父类,有什么要求等等... 多态代码演示: 1 /**日期:2016-03-

《逐梦旅程 WINDOWS游戏编程之从零开始》笔记8——光照与材质

第14章 绘制出质感的世界--光照与材质 1. 光照与光源 在Direct3D中的光源类型和光照类型是不同的两个概念,光照模型描述的是光线的反射特征,而光源类型主要强调的是能够产生这些光照模型的方式以及光线的位置,方向,强度等特征. 四大光照类型 环境光:基于整个自然界环境的整体亮度,称为环境光或者背景光,没有位置或者方向上的特征,只有一个颜色亮度值,不会衰减,在所有方向和所有物体表面上投射的环境光的数量是恒定不变的(有点像我们白天的自然光).在Direc3D中设置环境光可以直接使用setRen