文档章节

erlang中的link/0函数

格通
 格通
发布于 2016/10/09 11:17
字数 871
阅读 8
收藏 0
点赞 0
评论 0

erlang中的link/0函数可以使2个进程互相联系在一起,其中一个进程结束后,另外一个会收到这个进程的结束原因,我们可以根据这个原因信息来进行一些处理。

但要注意的是,link/0函数如果使用不当的话,在一个进程结束后,另外一个进程会紧跟着结束。下面直接上代码。

-module(linker).

%% API
-export([start/0,
	 start/1,
	 start2/1
	]).

%% 这里直接生成一个进程
start() ->
	spawn(fun() ->
		  receive
			  T ->
						  %% 输出任何收到的信息
			  io:format("T:~p, I~n", [T])
		  end
	  end).

%% 这里对进程进行link()函数操作
start(Pid) ->
	spawn(fun() ->
		  link(Pid),
		  receive
			  T ->
			  io:format("T:~p~n", [T])
		  end
	  end).

%% 跟上面start/1函数一样,多加了
%% process_flag(trap_exit, true) 操作
start2(Pid) ->
	spawn(fun() ->
		  process_flag(trap_exit, true),
		  link(Pid),
		  receive
			  T ->
			 io:format("T:~p, I am ~p ~n", [T, self()])
		  end
	  end).

上面建立了一个名为linker.erl的文件,下面我们在erlang shell里面进行操作:

$erlc linker.erl
$erl
Erlang/OTP 19 [erts-8.1] [source] [64-bit] [smp:3:3] [async-threads:10] [hipe] [kernel-poll:false]

Eshell V8.1  (abort with ^G)
1> Pid = linker:start().
<0.60.0>
2> Pid2 = linker:start(Pid).
<0.62.0>
3> processes().
[<0.0.0>,<0.1.0>,<0.4.0>,<0.30.0>,<0.31.0>,<0.33.0>,
 <0.34.0>,<0.35.0>,<0.36.0>,<0.38.0>,<0.39.0>,<0.40.0>,
 <0.41.0>,<0.42.0>,<0.44.0>,<0.45.0>,<0.46.0>,<0.47.0>,
 <0.48.0>,<0.49.0>,<0.50.0>,<0.51.0>,<0.52.0>,<0.53.0>,
 <0.54.0>,<0.58.0>,<0.60.0>,<0.62.0>]
4>
4> exit(Pid, kill_process).
true
5> processes().
[<0.0.0>,<0.1.0>,<0.4.0>,<0.30.0>,<0.31.0>,<0.33.0>,
 <0.34.0>,<0.35.0>,<0.36.0>,<0.38.0>,<0.39.0>,<0.40.0>,
 <0.41.0>,<0.42.0>,<0.44.0>,<0.45.0>,<0.46.0>,<0.47.0>,
 <0.48.0>,<0.49.0>,<0.50.0>,<0.51.0>,<0.52.0>,<0.53.0>,
 <0.54.0>,<0.58.0>]
6>

可以看到上面生成了2个进程,进行link()函数后,2个进程链接在一起。后来对Pid进行exit/2函数操作,2个进程没有任何信息就同时结束了。 下面我们继续探讨一下:

6> Pid3 = linker:start().
<0.67.0>
7> Pid4 = linker:start2(Pid3).
<0.69.0>
8> processes().
[<0.0.0>,<0.1.0>,<0.4.0>,<0.30.0>,<0.31.0>,<0.33.0>,
 <0.34.0>,<0.35.0>,<0.36.0>,<0.38.0>,<0.39.0>,<0.40.0>,
 <0.41.0>,<0.42.0>,<0.44.0>,<0.45.0>,<0.46.0>,<0.47.0>,
 <0.48.0>,<0.49.0>,<0.50.0>,<0.51.0>,<0.52.0>,<0.53.0>,
 <0.54.0>,<0.58.0>,<0.67.0>,<0.69.0>]
9> exit(Pid3, kill_process).
T:{'EXIT',<0.60.0>,kill_process}, I am <0.69.0>
true
10>processes().
[<0.0.0>,<0.1.0>,<0.4.0>,<0.30.0>,<0.31.0>,<0.33.0>,
 <0.34.0>,<0.35.0>,<0.36.0>,<0.38.0>,<0.39.0>,<0.40.0>,
 <0.41.0>,<0.42.0>,<0.44.0>,<0.45.0>,<0.46.0>,<0.47.0>,
 <0.48.0>,<0.49.0>,<0.50.0>,<0.51.0>,<0.52.0>,<0.53.0>,
 <0.54.0>,<0.58.0>]

可以看到多使用了process_flag(trap_exit, true)的函数后,不会跟着结束的进程无信息结束掉。 结论: 单独使用link/0函数,2个链接的进程会同时结束;而多使用了process_flag(trap_exit, true)的进程则不会。 这个在<<Designing for Scalability with Erlang/OTP>>书中有提到:

Remember, though, that links are bidirectional, so if the server dies for some reason while client and server are linked, this will by default kill the client too, which you may not want to happen. If that’s the case, use a monitor instead of a link, as we explain in “Monitors”. Exit signals can be trapped by calling the process_flag(trap_exit, true) function. This converts exit signals into messages of the form {'EXIT', Pid, Reason}, where Pid is the process identifier of the process that has died and Reason is the reason it has terminated. These messages are stored in the recipient’s mailbox and processed in the same way as all other messages. When a process is trapping exits, the exit signal is not propagated to any of the processes in its link set.Why does a process exit? This can happen for two reasons. If a process has no more code to execute, it terminates normally . The Reason propagated will be the atom normal. Abnormal termination is initiated in case of a runtime error, receiving an exit signal when not trapping exits, or by calling the exit BIFs. Called with a single argument, exit(Reason) will terminate the calling process with reason Reason, which will be propagated in the exit signal to any other processes to which the exiting one is linked. When the exit BIF is called with two arguments, exit(Pid, Reason), it sends an exit signal with reason Reason to the process Pid. This will have the same effect as if the calling process had terminated with reason Reason.

此博文同时发表在简书网页

© 著作权归作者所有

共有 人打赏支持
格通

格通

粉丝 7
博文 156
码字总数 39155
作品 0
广州
程序员
Erlang错误处理翻译片段

Before we go into details of the supervision and error handling in an Erlang system, we need see how Erlang processes terminate, or in Erlang terminology, exit. 我们先来看看Erl......

摩云菜 ⋅ 2013/09/13 ⋅ 1

erlang hibernate函数不会清除进程字典

一直想知道,erlang进程hibernate会不会把状态值给删除,通过代码知道,不会。 测试过程: 可以看到,更新了20个数据到进程字典里面,通过hibernate操作,可以把totalheapsize、heapsize给减...

格通 ⋅ 2016/11/03 ⋅ 0

[Erlang 0023] 理解Erlang/OTP gen_server

Erlang的OTP behaviour是对一些通用编程模式的抽象,在用Erlang 语言做开发时可以在behavior基础上快速构建出可用且可靠的功能.OTP behaviour包含genserver genevent genfsm supervisor.其中绝...

唐玄奘 ⋅ 2017/12/03 ⋅ 0

Linux 安装Erlang

Erlang目前已经是Fedora和Debian/Ubuntu软件仓库中的一部分。 Erlang目前最新的版本是OTP 17.0。Erlang是一种编程语言,用于构建大规模、高可伸缩性、高可用性的软实时系统的编程语言。它已经...

蓝狐乐队 ⋅ 2015/06/28 ⋅ 1

[Erlang 0017]Erlang/OTP基础模块 proc_lib

在梳理Erlang/OTP相关的内容时,我发现无论如何都无法避开proc_lib模块,说它是OTP的基础模块一点不为过. proclib模块的功能:This module is used to start processes adhering to the OTP Des...

唐玄奘 ⋅ 2017/12/03 ⋅ 0

elixir官方入门教程 进程

进程 和 链接 任务 状态 在Elixir中,所有代码都运行在进程内。进程相互独立,并发地运行,通过传送信息来交流。进程不是Elixir中唯一的并发基础,但它意味着能够构建分布式的,可容错的程序...

ljzn ⋅ 2016/08/04 ⋅ 0

为什么要用elixir编写并发应用

随着cpu数量的增多,程序越来越强调并发。 而提到并发,就经常会提到函数式编程。 函数式与面向对象的主要区别 函数式更强调精确性。 函数式用变形替代了修改。 Elixir中的进程 Elixir中的p...

ljzn ⋅ 2016/09/18 ⋅ 0

Cowboy的使用

使用rebar3创建erlang项目 修改rebar.config 创建conf文件夹 在conf下创建vm.args和sys.config文件 vm.args sys.config 修改src/test_cowboy.app.src 修改src/testcowboysup.erl 新建src/tes......

影狼 ⋅ 2017/12/22 ⋅ 0

笔记四 - OTP应用程序基本框架

最近工作忙,但是花了点时间看了些资料又学了很多东东,今天做一下application笔记. 看着这个单词就是应用程序意思,我就当它是一个应用程序了.那怎么使用呢? 第一步: 需要一个实现以下模式的模...

cloud ⋅ 2012/08/19 ⋅ 0

构建erlang的applicaion

erlang中构建自己的app是非常方便的,可以自己定制app,不过这里只是简单记录下erlang下典型的做法。 即是构建otp application。。 构建定制一个application可以通过xxx.app文件,可以把app...

千山万水 ⋅ 2015/10/15 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Jenkins实践3 之脚本

#!/bin/sh# export PROJ_PATH=项目路径# export TOMCAT_PATH=tomcat路径killTomcat(){pid=`ps -ef | grep tomcat | grep java|awk '{print $2}'`echo "tom...

晨猫 ⋅ 今天 ⋅ 0

Spring Bean的生命周期

前言 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解。 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: Spring 只帮我们管理单例模...

素雷 ⋅ 今天 ⋅ 0

zblog2.3版本的asp系统是否可以超越卢松松博客的流量[图]

最近访问zblog官网,发现zlbog-asp2.3版本已经进入测试阶段了,虽然正式版还没有发布,想必也不久了。那么作为aps纵横江湖十多年的今天,blog2.2版本应该已经成熟了,为什么还要发布这个2.3...

原创小博客 ⋅ 今天 ⋅ 0

聊聊spring cloud的HystrixCircuitBreakerConfiguration

序 本文主要研究一下spring cloud的HystrixCircuitBreakerConfiguration HystrixCircuitBreakerConfiguration spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/......

go4it ⋅ 今天 ⋅ 0

二分查找

二分查找,也称折半查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于...

人觉非常君 ⋅ 今天 ⋅ 0

VS中使用X64汇编

需要注意的是,在X86项目中,可以使用__asm{}来嵌入汇编代码,但是在X64项目中,再也不能使用__asm{}来编写嵌入式汇编程序了,必须使用专门的.asm汇编文件来编写相应的汇编代码,然后在其它地...

simpower ⋅ 今天 ⋅ 0

ThreadPoolExecutor

ThreadPoolExecutor public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ......

4rnold ⋅ 昨天 ⋅ 0

Java正无穷大、负无穷大以及NaN

问题来源:用Java代码写了一个计算公式,包含除法和对数和取反,在页面上出现了-infinity,不知道这是什么问题,网上找答案才明白意思是负的无穷大。 思考:为什么会出现这种情况呢?这是哪里...

young_chen ⋅ 昨天 ⋅ 0

前台对中文编码,后台解码

前台:encodeURI(sbzt) 后台:String param = URLDecoder.decode(sbzt,"UTF-8");

west_coast ⋅ 昨天 ⋅ 0

实验楼—MySQL基础课程-挑战3实验报告

按照文档要求创建数据库 sudo sercice mysql startwget http://labfile.oss.aliyuncs.com/courses/9/createdb2.sqlvim /home/shiyanlou/createdb2.sql#查看下数据库代码 代码创建了grade......

zhangjin7 ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部