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

什么是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. 通过修改host文件来允许和禁止主机的访问

    通过修改host文件来允许和禁止主机的访问 修改/etc/hosts.deny,加入"sshd:ALL" 修改/etc/hosts.allow,加入"sshd:192.1 ...

  2. Python 实现有道翻译命令行版

    一.个人需求 由于一直用Linux系统,对于词典的支持特别不好,对于我这英语渣渣的人来说,当看英文文档就一直卡壳,之前用惯了有道词典,感觉很不错,虽然有网页版的但是对于全站英文的网页来说并不支持.索性 ...

  3. Python:字符编码详解

    相关文章 Python中文编码问题:为何在控制台下输出中文会乱码及其原理 1. 字符编码简介 1.1. ASCII ASCII(American Standard Code for Informati ...

  4. 在cxf中使用配置避免增加字段导致客户端必须更新、同步实体属性的问题

    在使用cxf实现webservice时,经常碰到的问题就是如果在服务端,修改了一个接口的签名实现,如增加一个字段,或者删除一个字段.在这种情况下,在默认的配置中,就会报以下的错误信息: org.apa ...

  5. Revit中绘制带坡度管道

    激活管道绘制命令出现绘制管道上下文菜单,可以根据需要设置管道坡度值,是向上坡度还是向下坡度,其中两个命令非常有用,一个是继承高程,一个是忽略坡度以连接.在Revit建模中尝尝碰到一些带有坡度的管道,比 ...

  6. gson 自定义对象转换格式

    有时候我们希望gson按照我们想要的方式转换,比如将日期转换为时间戳 class GsonBuilderUtil { public static Gson create() { GsonBuilder ...

  7. phpredis中文手册——《redis中文手册》 php版

    本文是参考<redis中文手册>,将示例代码用php来实现,注意php-redis与redis_cli的区别(主要是返回值类型和参数用法). 目录(使用CTRL+F快速查找命令): Key ...

  8. [salesforce] standard button

    Use Case In Salesforce, when you click on the standard ‘New’ button on a Related List to create a ne ...

  9. C#控制其它程序

    [DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]        ...

  10. 分布式代码管理 tortoisehg mercurial

    下载客户端:            https://bitbucket.org/tortoisehg/files/downloads mercurial客户端下载:http://mercurial.s ...