再谈Erlang代码热替换
在《Erlang程序设计》中E4部分,通过一个小例子展示了代码的动态加载,两个module代码如下:
a.erl
- -module(a).
- -compile(export_all).
- -import(b, [x/0]).
- start(Tag) ->
- spawn(fun() -> loop(Tag) end).
- loop(Tag) ->
- timer:sleep(3000),
- Val = x(),
- io:format("Vsn1 (~p) b:x() = ~p~n", [Tag, Val]),
- loop(Tag).
-module(a). -compile(export_all). -import(b, [x/0]).start(Tag) ->spawn(fun() -> loop(Tag) end).loop(Tag) ->timer:sleep(3000),Val = x(),io:format("Vsn1 (~p) b:x() = ~p~n", [Tag, Val]),loop(Tag).
b.erl
- -module(b).
- -compile(export_all).
- x() -> 1.
-module(b). -compile(export_all).x() -> 1.
这个例子中是通过c(a), c(b)的方式编译修改后的a.erl 和 b.erl,这里其实是做了两件事:
1,编译module
2,load module
所以我们在这个例子中,可以看到如果我们修改了b的代码,然后在Erlang shell中通过:
c(b). 我们可以立即看到“新”的b module在运行了。
在Erlang中每个Module可以保存2个version,如果再有第三个version加入,那么首先要通过code:purse/1清理先前的版本,随后才可以load新的module。
在Erlang内部,当有新的Module被调用时,旧的Module的Export 函数将被新的Export函数代替,因此当我们实用M:F(A)的方式调用函数时,将调用最新代码。
让我们启动a module:
- > a:start(one).
- Vsn1 (one) b:x() = 1
> a:start(one). Vsn1 (one) b:x() = 1
随后我们修改a.erl:
- -io:format("Vsn1 (~p) b:x() = ~p~n", [Tag, Val]),
- +io:format("Vsn2 (~p) b:x() = ~p~n", [Tag, Val]),
-io:format("Vsn1 (~p) b:x() = ~p~n", [Tag, Val]), +io:format("Vsn2 (~p) b:x() = ~p~n", [Tag, Val]),
然后编译a.erl:
- $ erlc a.erl
$ erlc a.erl
当前,在Erlang中只有Vsn1版本的a,回到erlang shell中,加载Vsn2:
- > code:load_file(a).
> code:load_file(a).
现在在Erlang中有Vsn1和Vsn2两个版本的a module。
我们在启动一个新的a process:
- > a:start(two).
- Vsn2 (two) b:x() =1
> a:start(two). Vsn2 (two) b:x() =1
好了让我们再次修改a.erl:
- -io:format("Vsn2 (~p) b:x() = ~p~n", [Tag, Val]),
- +io:format("Vsn3 (~p) b:x() = ~p~n", [Tag, Val]),
-io:format("Vsn2 (~p) b:x() = ~p~n", [Tag, Val]), +io:format("Vsn3 (~p) b:x() = ~p~n", [Tag, Val]),
然后编译a.erl:
- $ erlc a.erl
$ erlc a.erl
注意:此时Erlang shell中并没有加载Vsn3版本的代码,因为我们没有使用c(a)的方式编译加载a module。我们可以测试一下:
- >a:start(three).
- <0.38.0>
- Vsn2 (three) b:x() = 1
>a:start(three). <0.38.0> Vsn2 (three) b:x() = 1
毫无疑问,还是Vsn2
接下来我们想加载Vsn3版本的a,回到Erlang shell:
- > code:load_file(a).
- =ERROR REPORT==== 14-Jan-2009::23:16:23 ===
- Loading of /home/litao/erl/a.beam failed: not_purged
- {error,not_purged}
- =ERROR REPORT==== 14-Jan-2009::23:16:23 ===
- Module a must be purged before loading
> code:load_file(a). =ERROR REPORT==== 14-Jan-2009::23:16:23 === Loading of /home/litao/erl/a.beam failed: not_purged {error,not_purged}=ERROR REPORT==== 14-Jan-2009::23:16:23 === Module a must be purged before loading
oh,产生了一个错误信息,返回{error,not_purged},现在已经有Vsn1,Vsn2两个a module了,这第三个被拒绝了。我们必须调用code:purge/1清除Vsn1:
- > code:purge(a).
- true
- Vsn2 (three) b:x() = 1
- Vsn2 (two) b:x() = 1
> code:purge(a). true Vsn2 (three) b:x() = 1 Vsn2 (two) b:x() = 1
返回true,同时Vsn1版本的a process已经被kill了,现在只有Vsn2了。接下来加载我们的Vsn3吧:
- > code:load_file(a).
- {module,a}
- Vsn2 (two) b:x() = 1
- Vsn2 (three) b:x() = 1
- 8> a:start(five).
- <0.43.0>
- Vsn2 (three) b:x() = 1
- Vsn2 (two) b:x() = 1
- Vsn3 (five) b:x() = 1
> code:load_file(a). {module,a} Vsn2 (two) b:x() = 1 Vsn2 (three) b:x() = 1 8> a:start(five). <0.43.0> Vsn2 (three) b:x() = 1 Vsn2 (two) b:x() = 1 Vsn3 (five) b:x() = 1
好了Vsn2成了旧版本,Vsn3成了新版本。
自己动手实验一下吧!
Update:
code:soft_purge(Module),如果没有process运行旧的Module,则返回true(表明此Module可以被温和的purge);否则返回false。
可以通过erlang:check_process_code(Pid, Module)检测Process是否运行某个Module的Old version,这个检测不会检测process的运行时,判断当前函数是否为old
请注意:code:purge 和 code:soft_purge 针对的是old version,如果当前module只有一个version,那么 purge返回false, soft_purge返回true.
转载于:https://www.cnblogs.com/xiayong123/archive/2012/01/15/3717159.html
再谈Erlang代码热替换相关推荐
- arthas classclassloader相关命令之二:jad、mc、redifine实现代码热更新(热替换)
jad mc mc就类似于javac redefine redefine只能修改现有方法,不能增加属性和方法 redefine的限制 案例:redefine结合jad.mc一起使用实现代码热替换 总结
- webpack5 基础配置8 devServer 模块热替换HMR, 框架的HRM, HRM原理
dev Server 之前运行一直是手动打开页面,修改代码后,每次都要run build非常麻烦. 第一种是通过watch来解决,每次代码一修改就自动编译然后重新渲染. 可以看到刚我们修改了代码,重新 ...
- 赵聪慧 java,基于Instrumentation的JAVA代码暖替换
基于Instrumentation的JAVA代码热替换 理类用来获取 Instrumentation 实例package com.codeconch.util; import java.lang.in ...
- java 热替换 匿名类_Java 类的热替换
Java 类的热替换 -- 概念.设计与实现 构建基于 Java 的在线升级系统 孙 鸣 和 邓 辉 2010 年 1 月 14 日发布 Java ClassLoader 技术剖析 在本文中,我们将不 ...
- java 热替换_class卸载、热替换和Tomcat的热部署的分析
所以一个class被一个ClassLoader实例加载过的话,就不能再被这个ClassLoader实例再次加载(这里的加载指的是,调用了defileClass(...)放方法,重新加载字节码.解析.验 ...
- 再谈编程范式-程序语言背后的思想
link link 编程范式 托马斯.库尔提出"科学的革命"的范式论后,Robert Floyd在1979年图灵奖的颁奖演说中使用了编程范式一词.编程范式一般包括三个方面,以OOP ...
- Java 类的热替换---转载
构建基于 Java 的在线升级系统 Java ClassLoader 技术剖析 在本文中,我们将不对 Java ClassLoader 的细节进行过于详细的讲解,而是关注于和构建在线升级系统相关的基础 ...
- webpack 3 零基础入门教程 #12 - 如何使用模块热替换 HMR 来处理 CSS
模块热替换 是什么意思? 以前我们使用的 webpack --watch 或 webpack-dev-server 的功能是监听文件改变,就自动刷新浏览器,而这个 模块热替换 不用刷新浏览器,它是只让 ...
- iOS代码质量要求_Unity移动端代码热更新技术学习总结
为什么需要热更新 游戏总是伴随着不断的开发与维护,我们不能要求玩家每次都将游戏客户端卸载重装,所以需要热更新技术来在不需要重装客户端的情况下下载更新游戏里的代码(其实资源也需要热更新,但是因为操作系统 ...
最新文章
- 目标检测--Object Detection via Aspect Ratio and Context Aware
- AngularJS实现产品列表(页面搜索,排序)
- Linux下的静态库、动态库和动态加载库
- 18.外部相机校准——介绍,几何相机校正,自由度 测验,刚体变换,符号_1
- 如何强大且优雅的搞定Linux文件系统,值得一读!
- 区块链100讲:带你走进EOS的存储系统
- 华为n3计算机在哪里,在华为nova3i中连接电脑的两种方法介绍
- Csharp四种简单的排序算法
- C++ vector和set的区别
- 信息发布系统 Jquery+MVC架构开发(3) 解决方案创建
- 计算机网络简历自我认识,计算机网络专业简历的自我评价
- 2022年10月总结 (距离激动人心的928已经过去一个多月了)
- 超清视频制作:视频补帧+超分辨率
- exchange2016卸载报错安装程序无法卸载,因为mscorsvw(9476)具有打开的文件
- KNY三人组对YiSmile小程序的项目总结
- shell脚本循环执行任务的脚本
- CANoe:CAPL周期发送CANFD报文
- 比较超声与临床体检检查早期关节炎患者手部屈肌腱腱鞘炎
- 韩信点兵(hanxin)--算法竞赛经典习题2-2:相传韩信才智过人,从不清点自己军队的人数,只要让士兵先后以三人一排、五人一排、七人一排地变换队形,他每次只要掠一眼队伍的排尾就知道总数(C++实现)
- c 语言中星号什么意思,Objective-C中的星号*是什么意思?