您的位置:首页 > 其它

面对软件错误构建可靠的分布式系统_笔记06

2009-02-01 22:14 330 查看
3.5.6进程连接与监视者

3.5.6.1进程连接:

将一组进程组合在一起,其中任意一个进程错误死掉,其它进程都被连带停掉

进程连接是对称的,A连接到B,则B自动也连接到A

eg: 在A进程中,执行

B = spawn_link(fun() -> ... end).

则A和B连接了,当B发生异常死掉时,会发送退出信号{'EXIT',B,Why}给A进程,当Why不为normal时,则A也会死掉。

例外,当接收进程是个系统进程时,即使收到退出信号,也不会退出(除非发送exit(Pid, kill))

process_flag(trap_exit, true). 变为系统进程

eg: 系统进程处理其它进程错误的典型代码

start() ->spawn(fun go/0).

go() ->

process_flag(trap_exit, true),

loop().

loop() ->

receive

{'EXIT',P,Why} ->

.... handle the error

end.

主动发送错误消息:

exit(Pid, Why). 发送方伪装死亡,接收方Pid将收到退出信号

exit(Pid, kill).发送"不可阻挡的退出信号",包括系统进程在内的进程都将退出

3.5.6.2进程监视者:

非对称的连接,一个进程可以监视其它进程,一个多用在C/S系统中,Server死掉时,可以杀掉所有client,而某个client死掉时,不能杀死server

eg: 在进程A中设置监视者, A和B都不必是系统进程

Ref = erlang:monitor(process, B).

当B死掉时,B向A发送消息

{'DOWN', Ref, process, B, Why}

3.6分布式编程

两个原语:

spawn(Node, Fun):在远端节点Node上,生成函数是Fun的进程

monitor(Node):用来监视整个节点的行为,而不仅仅是某个进程

3.7端口ports

进程与外界通信的机制:每个端口有个关联的"控制进程",只有此进程才能往此端口发送消息,此端口收到的消息都发送到此进程。

open_port/2创建,一般创建进程是此端口的控制进程,也可以改变

eg:端口发送消息

Port ! {Pid, Command} //端口Port发送给Pid,执行Command命令,有三种形式

(1)Port ! {Pid, {command, Data}}.发送命令command,传递数据Data,

(2)Port ! {Pid, close}. 关闭端口,端口会向控制进程回复 {Port, closes}消息

(3)Port ! {connect, Pid1}.将端口的控制进程改为Pid1,端口给原控制进程发送{Port, connected}消息,此后的消息将发送给Pid1

3.8动态代码

可以动态支持版本更新(最多两个版本同时运行)。更新版本后,旧程序有两种方式:可以运行新程序,可以运行旧程序

(1)动态替换为新版本

当代码是通过全修饰名被调用的,即ModuleName:FuncName调用,则更新后,会调用新版本

-module(m)

...

loop(Data, F) ->

receive

{From, Q} ->

{Reply, Data1} = F(Q,Data),

m:loop(data1,F)

end.

(2)仍然调用旧版本

-module(m)

...

loop(Data, F) ->

receive

{From, Q} ->

{Reply, Data1} = F(Q,Data),

loop(data1,F)

end.

(3)最多支持两个版本,如果再有版本更新,则仍执行最旧的版本的进程将被杀死

3.9类型符号

相当于类型定义:type定义函数,deftype定义类型

原始类型包括

int(), atom(), pid(), ref()引用类型,float(),port(),bin()二进制类型

可以自定义类型

+deftype name1() = name2() = ... = Type.

+deftype bool() = true | false.

+deftype weekday() = monday|tuesday|wednesday|thursday|friday.

+deftype weekend() = saturday() | sunday().

+deftype day() = weekday()|weekend().

+deftype string() = [int()].

+deftype day2() = number() = int().

+deftype town() = street() = string().

自定义函数类型

+type functionName(T1,T2,...Tn) ->T.

+type factorial(int()) -> int().

+type day2int(day()) -> int().

+type address(person()) -> {town(), street(),number()}.

+type fun(T1,T2...Tn) -> T end. 匿名函数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: