这篇文章还不是最终版,有时间时,我会再来补充完善。

什么是link

Erlang程序基于进程建模,进程之间的交互机制有收发消息,link和monitor。其中,收发消息通常用于正常的进程间通讯,而link和monitor多用于异常情况处理,本文从应用的角度介绍和分析link机制。link是双向全联通的,用来将两个或多个进程绑定在一起,绑定在一起之后,VM会保证在有进程退出时,对与其绑定在一起的进程执行特定的操作。

创建link和取消link

Two processes can be linked to each other. A link between two

processes Pid1 and Pid2 is created by Pid1 calling the BIF

link(Pid2)(or vice versa). There also exists a number a spawn_link

BIFs, which spawns and links to a process in one operation.

Links are bidirectional and there can only be one link between two

processes.Repeated calls to link(Pid) have no effect.

A link can be removed bycalling the BIF unlink(Pid).

当有进程退出时

发送Exit Signal

When a process terminates, it will terminate with an exit reason as

explained in Process Termination above. This exit reason is emitted in

an exit signal to all linked processes.

A process can also call the function exit(Pid,Reason). This will

result in an exit signal with exit reason Reason being emitted to Pid,

but does not affect the calling process.

Exit Signal的默认处理方式

The default behaviour when a process receives an exit signal with an

exit reason other than normal, is to terminate and in turn emit exit

signals with the same exit reason to its linked processes. An exit

signal with reason normal is ignored

将Exit Signal转换为普通的进程消息

A process can be set to trap exit signals by calling:

process_flag(trap_exit, true)

When a process is trapping exits, it will not terminate when an exit

signal is received. Instead, the signal is transformed into a

message{'EXIT',FromPid,Reason} which is put into the mailbox of the

process just like a regular message.

An exception to the above is if the exit reason is kill, that is if

exit(Pid,kill) has been called. This will unconditionally terminate

the process, regardless of if it is trapping exit signals or not.

link与OTP的关系

OTP作为Erlang官方的编程框架被广泛应用,在OTP的实现中,link机制被广泛的应用。

Erlang has a built-in feature for error handling between processes.

Terminating processes will emit exit signals to all linked processes,

which may terminate as well or handle the exit in some way. This

feature can be used to build hierarchical program structures where

some processes are supervising other processes, for example restarting

them if they terminate abnormally.

Refer to OTP Design Principles for more information about OTP

supervision trees, which uses this feature.

gen_server

假设存在a,b两个进程,其中b是gen_server。我们在进程a中调用b:start_link(),使两个进程link在一起,然后来讨论一些异常情况。

  • a进程正常退出 -> b进程正常运行
  • a进程异常退出 -> b进程退出
  • a进程正常退出, b进程中调用了process_flag(trap_exit, true) -> b进程不会收到exit msg,退出
  • a进程异常退出, b进程中调用了process_flag(trap_exit, true) -> b进程不会收到exit msg,退出
  • b进程正常退出 -> a进程正常运行
  • b进程异常退出 -> a进程退出
  • b进程正常退出, a进程中调用了process_flag(trap_exit, true) -> a进程收到{'EXIT',Pid_b,normal}
  • b进程异常退出, a进程中调用了process_flag(trap_exit, true) -> a进程收到{'EXIT',Pid_b,Reason}

看起来第3项和第4项不太正常,似乎跟刚刚介绍的erlang link机制冲突了。出现这种现象的原因,是gen_server不是普通进程,它在一个普通的进程上,添加一些默认的行为,具体到这个问题,就是gen_server在收到来自父进程(>调用start_link>的进程)的{'EXIT',Pid_Parent,Reason}

decode_msg(Msg, Parent, Name, State, Mod, Time, Debug, Hib) ->
case Msg of
{system, From, get_state} ->
sys:handle_system_msg(get_state, From, Parent, ?MODULE, Debug,
{State, [Name, State, Mod, Time]}, Hib);
{system, From, {replace_state, StateFun}} ->
NState = try StateFun(State) catch _:_ -> State end,
sys:handle_system_msg(replace_state, From, Parent, ?MODULE, Debug,
{NState, [Name, NState, Mod, Time]}, Hib);
{system, From, Req} ->
sys:handle_system_msg(Req, From, Parent, ?MODULE, Debug,
[Name, State, Mod, Time], Hib);
{'EXIT', Parent, Reason} ->
terminate(Reason, Name, Msg, Mod, State, Debug);
_Msg when Debug =:= [] ->
handle_msg(Msg, Parent, Name, State, Mod);
_Msg ->
Debug1 = sys:handle_debug(Debug, fun print_event/3,
Name, {in, Msg}),
handle_msg(Msg, Parent, Name, State, Mod, Debug1)
end.

link与业务建模

待续

Erlang进程的Link机制的更多相关文章

  1. erlang进程监控:link和monitor

    Erlang最开始是为了电信产品而发展起来的语言,因为这样的目的,决定了她对错误处理的严格要求.Erlang除了提供exception,try catch等语法,还支持Link和Monitor两种监控 ...

  2. Erlang进程堆垃圾回收机制

    原文:Erlang进程堆垃圾回收机制 作者:http://blog.csdn.net/mycwq 每一个Erlang进程创建之后都会有自己的PCB,栈,私有堆.erlang不知道他创建的进程会用到哪种 ...

  3. 深入理解docker的link机制

    https://yq.aliyun.com/articles/55912 摘要: 什么是docker的link机制 同一个宿主机上的多个docker容器之间如果想进行通信,可以通过使用容器的ip地址来 ...

  4. 从Erlang进程看协程思想

    从Erlang进程看协程思想 多核慢慢火了以后,协程类编程也开始越来越火了.比较有代表性的有Go的goroutine.Erlang的Erlang进程.Scala的actor.windows下的fibr ...

  5. erlang进程与操作系统线程

    erlang多进程与多线程: 在erlang开发中,我们面对的最小执行单位是进程,当然这个进程并不是系统层面上的进程,也不是线程.而是基于erlang运行时系统的一个进程.那么erlang的多进程是如 ...

  6. erlang进程概述

    一.概述 与大多数的进程相反,Erlang中的并发很廉价,派生出一个进程就跟面向对象的语言中分配一个对象的开销差不多. 在启动一个复杂的运算时,启动运算.派生进程以及返回结果后,所有进程神奇的烟消云散 ...

  7. Linux进程组调度机制分析【转】

    转自:http://oenhan.com/task-group-sched 又碰到一个神奇的进程调度问题,在系统重启过程中,发现系统挂住了,过了30s后才重新复位,真正系统复位的原因是硬件看门狗重启的 ...

  8. 一篇文章了解相见恨晚的 Android Binder 进程间通讯机制【转】

    本文转载自:https://blog.csdn.net/freekiteyu/article/details/70082302 Android-Binder进程间通讯机制 概述 最近在学习Binder ...

  9. Android Binder 进程间通讯机制梳理

    什么是 Binder ? Binder是Android系统中进程间通讯(IPC)的一种方式,也是Android系统中最重要的特性之一.Binder的设计采用了面向对象的思想,在Binder通信模型的四 ...

随机推荐

  1. Mysql:Error Code 1235,This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME 错误解决

    This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME 错误解决 这次国庆节回来后的测试中,在一个Mysql表达式 ...

  2. CCNA实验4:HDLC和PPP

    一.HDLC封装 router9和11上分别配置s0/0如下 conf t int s0/0 encapsulation hdlc do show int s0/0 ip address x.x.x. ...

  3. 高级屏幕空间反射: Screen Space Reflection (SSSR)

    SSSR进一步调优,对标寒霜级技术水平,实现方式为Direct3D 11+自主实现实时渲染引擎,方法为对比测试.实现已经有段时间了,还是简要更新下吧.以下画面中的SSSR效果全部采用1:4 resol ...

  4. 最近使用ajaxFileUpload和Jcrop来实现图片上传和截图,出现一个图片无法更换的问题

    使用setImage 都无法更换 刷新图片 找了很久 什么方法都找过,最后发现...... 原来是 上传的图片的命名问题... 每次上传的图片 保存后都是同样的图片, 所以返回路径都是一样... jc ...

  5. Java 反射练习

    已同步更新至个人blog:http://dxjia.cn/2015/08/java-reflect/ 引用baidubaike上对JAVA反射的说明,如下:JAVA反射机制是在运行状态中,对于任意一个 ...

  6. ECShop商品详细页 实现尺码颜色关联显示库存数量

    效果如下: 要开模板文件 goods.dwt  把选择尺码跟颜色的代码替换成如下,(不同模板代码可能不一样,对照去替换) <!-- {foreach from=$spec.values item ...

  7. android studio 编译加速

    1. http://www.52codes.net/article/658.html 2.http://my.oschina.net/sammy1990/blog/388846 3.http://st ...

  8. Firefox终于返回到了Debian stable

    6月8日,firefox 45.2以安全修复包的名义回到了Debian oldstable (即wheezy),两天以后,Debian 8 jessie里面也有了(https://packages.d ...

  9. njoj 1251 zlly长了一张包子脸

    njoj 1251 zlly长了一张包子脸 题意: zlly长了一张包子脸.他特别喜欢吃糖果.如今他手头有若干种糖果,每种糖果有个口味值,每种糖果有无数多个.然后娄童鞋也很喜欢吃糖果.他的口味特别广泛 ...

  10. python Flask :TypeError: 'dict' object is not callable

    flask 基于Werkzeug .. @moudule.route('/upload', methods=['GET', 'POST']) def upload_file(): global _fl ...