<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_回头再说  坚强2002的博客</title><subtitle type="text">在每个新的一年三百六十五天我们都每天进步一点点......</subtitle><id>http://feed.cnblogs.com/blog/u/20888/rss</id><updated>2012-02-03T06:22:02Z</updated><author><name>坚强2002</name><uri>http://www.cnblogs.com/me-sa/</uri></author><generator>CNBlogs BlogServer</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/me-sa/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/20888/rss"/><entry><id>http://www.cnblogs.com/me-sa/archive/2012/02/01/erlang0035.html</id><title type="text">[Erlang 0035] Erlang SMP</title><summary type="text">Erlang SMP使用操作系统线程实现多个调度器,利用了多核多CPU的优势并把实现细节对开发者隐藏起来,  可以不修改代码甚至不用重新编译就可以使用;使用SMP可以有非常灵活的启动选择和运行时调整的方法入口;</summary><published>2012-02-01T04:36:00Z</published><updated>2012-02-01T04:36:00Z</updated><author><name>坚强2002</name><uri>http://www.cnblogs.com/me-sa/</uri></author><link rel="alternate" href="http://www.cnblogs.com/me-sa/archive/2012/02/01/erlang0035.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/me-sa/archive/2012/02/01/erlang0035.html"/><content type="html">&lt;div&gt;&lt;span&gt;Erlang SMP&lt;/span&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;Erlang SMP (Symmetrical Multi Processor)在97-98年左右开始,项目按照先跑起来再优化的开发策略("First make it work, then measure, then optimize".),在2006年R11B发布了第一个稳定版本;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;原理&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;没有SMP支持的Erlang VM只有一个Scheduler运行于主线程;Scheduler从运行队列中取出需要处理的Erlang进程和IO-job;由于只有一个Scheduler没有必要对数据加锁;见下图:&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/17329/2012020112282584.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp;有SMP支持的Erlang VM 可以有1~1024个Scheduler,每一个Scheduler都会运行于一个独立的操作系统线程;操作系统决定它是否要在不同的核上运行.由于多个Scheduler就要对数据加锁,一个Erlang进程可能前后被多个Scheduler调度;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/17329/2012020112283789.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;性能&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;div&gt;&#xD;
&lt;p&gt;下面这个数据比较老了(2008年1月),但是还可以做参考:&lt;/p&gt;&#xD;
&lt;p&gt;Measurements from a real telecom product showed a 1.7 speed improvement between a single and a dual core system.&lt;/p&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;The SMP VM with only one scheduler is slightly slower (10%) than the non SMP VM.&amp;nbsp;&lt;br /&gt;&#xD;
This is because the SMP VM need to use locks for all shared datastructures. But as&amp;nbsp;long as there are no lock-conflicts the overhead caused by locking is not that high (it&amp;nbsp;is the lock conflicts that takes time).&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&#xD;
This explains why it in some cases can be more efficient to run several SMP VM's&amp;nbsp; with one scheduler each instead on one SMP VM with several schedulers. Of course&amp;nbsp; the running of several VM's require that the application can run in many parallel tasks&amp;nbsp;which has no or very little communication with each other.&amp;nbsp;&lt;/blockquote&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;p&gt;&lt;strong&gt;应用&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div&gt;&amp;nbsp; 从OTP R12B开始只要操作系统告知当前是多CPU(多核),SMP就会自动开启并设定Scheduler个数和CPU或核的数量一致;我们启动一下看看:&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;Erlang R15B (erts-&lt;span style="color: #800080;"&gt;5&lt;/span&gt;.&lt;span style="color: #800080;"&gt;9&lt;/span&gt;) [source] [&lt;span style="color: #800080;"&gt;64&lt;/span&gt;-bit] [&lt;span style="color: #008080;"&gt;smp:&lt;/span&gt;&lt;span style="color: #800080;"&gt;8&lt;/span&gt;:&lt;span style="color: #800080;"&gt;8&lt;/span&gt;] [async-&lt;span style="color: #008080;"&gt;threads:&lt;/span&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;] [hipe] [kernel-&lt;span style="color: #008080;"&gt;poll:&lt;/span&gt;false]&lt;br /&gt;&lt;br /&gt;Eshell V5.&lt;span style="color: #800080;"&gt;9&lt;/span&gt;  (abort with ^G)&lt;br /&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;gt; &lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;检查一下服务器CPU信息&lt;/div&gt;&#xD;
&lt;div&gt;# grep "model name" /proc/cpuinfo | cut -f2 -d:&lt;br /&gt; Intel(R) Xeon(R) CPU&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; E5506&amp;nbsp; @ 2.13GHz&lt;br /&gt; Intel(R) Xeon(R) CPU&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; E5506&amp;nbsp; @ 2.13GHz&lt;br /&gt; Intel(R) Xeon(R) CPU&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; E5506&amp;nbsp; @ 2.13GHz&lt;br /&gt; Intel(R) Xeon(R) CPU&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; E5506&amp;nbsp; @ 2.13GHz&lt;br /&gt; Intel(R) Xeon(R) CPU&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; E5506&amp;nbsp; @ 2.13GHz&lt;br /&gt; Intel(R) Xeon(R) CPU&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; E5506&amp;nbsp; @ 2.13GHz&lt;br /&gt; Intel(R) Xeon(R) CPU&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; E5506&amp;nbsp; @ 2.13GHz&lt;br /&gt; Intel(R) Xeon(R) CPU&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; E5506&amp;nbsp; @ 2.13GHz&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;可以看到8核的机器启动的时候自动开启了smp:8:8,这两个数字是什么意思?&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;div&gt;&lt;strong&gt;+S Schedulers:SchedulerOnline&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;Sets the amount of scheduler threads to create and scheduler threads to set online when SMP support has been enabled. Valid range for both values are 1-1024. If the Erlang runtime system is able to determine the amount of logical processors configured and logical processors available, Schedulers will default to logical processors configured, and SchedulersOnline will default to logical processors available; otherwise, the default values will be 1. Schedulers may be omitted if :SchedulerOnline is not and vice versa. The amount of schedulers online can be changed at run time via erlang:system_flag(schedulers_online, SchedulersOnline).&lt;/div&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;注意:&lt;/div&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&amp;nbsp; 如果设定的数量超出CPU数或者核数并不能得到什么好处&lt;/li&gt;&#xD;
&lt;li&gt;&amp;nbsp; 有的操作系统可以使用tasket之类的命令绑定CPU,Erlang VM只会检测可用的CPU数,因为绑定这事可能在任何时刻发生;SchedulersOnline&amp;nbsp;就是实际可用的CPU数或核数;&lt;/li&gt;&#xD;
&lt;li&gt;&amp;nbsp;运行时是可以调整该参数的&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;div&gt;如果要关闭SMP 可以使用下面的启动参数:&lt;/div&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;strong&gt;-smp [enable|auto|disable]&lt;/strong&gt;&lt;br /&gt;&#xD;
-smp enable and -smp starts the Erlang runtime system with SMP support enabled. This may fail if no runtime system with SMP support is available. -smp auto starts the Erlang runtime system with SMP support enabled if it is available and more than one logical processor are detected. -smp disable starts a runtime system without SMP support.&amp;nbsp;&lt;/span&gt;&lt;span&gt;&lt;strong&gt;By default -smp auto will be used&lt;/strong&gt;&lt;/span&gt;&lt;span&gt;&amp;nbsp;unless a conflicting parameter has been passed, then -smp disable will be used. Currently only the -hybrid parameter conflicts with -smp auto.&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; SMP使用操作系统线程实现多个调度器,利用了多核多CPU的优势并把实现细节对开发者隐藏起来, &amp;nbsp;可以不修改代码甚至不用重新编译就可以使用;使用SMP可以有非常灵活的启动选择和运行时调整的方法入口;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;相关资料:&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div&gt;[1] 本文截图来自Ericsson的一篇文档:&lt;a href="http://www.erlang.org/euc/08/euc_smp.pdf" target="_blank"&gt;Inside the Erlang VM&amp;nbsp;with focus on SMP&amp;nbsp;&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div&gt;[2] Some facts about Erlang and SMP&amp;nbsp;&amp;nbsp;http://erlang.2086793.n4.nabble.com/Some-facts-about-Erlang-and-SMP-td2108770.html&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;/div&gt;&lt;img src="http://www.cnblogs.com/me-sa/aggbug/2334380.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2012/02/01/erlang0035.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/me-sa/archive/2012/01/31/erlang0034.html</id><title type="text">[Erlang 0034] Erlang iolist</title><summary type="text">既然Erlang中有List,那iolist又是为了解决什么问题而设计的呢?</summary><published>2012-01-31T09:58:00Z</published><updated>2012-01-31T09:58:00Z</updated><author><name>坚强2002</name><uri>http://www.cnblogs.com/me-sa/</uri></author><link rel="alternate" href="http://www.cnblogs.com/me-sa/archive/2012/01/31/erlang0034.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/me-sa/archive/2012/01/31/erlang0034.html"/><content type="html">&lt;div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;p&gt;问题的缘起是芒果在使用mochiweb的过程中遇到一个异常，在google的讨论组中我找到了同样的问题：&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;=ERROR REPORT==== &lt;span style="color: #800080;"&gt;7&lt;/span&gt;-Apr-&lt;span style="color: #800080;"&gt;2011&lt;/span&gt;::&lt;span style="color: #800080;"&gt;18&lt;/span&gt;:&lt;span style="color: #800080;"&gt;58&lt;/span&gt;:&lt;span style="color: #800080;"&gt;22&lt;/span&gt; === &lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;web request failed&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;path:&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;cfsp/entity&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;type:&lt;/span&gt; error &lt;br /&gt;&lt;span style="color: #008080;"&gt;what:&lt;/span&gt; badarg &lt;br /&gt;&lt;span style="color: #008080;"&gt;trace:&lt;/span&gt; [{erlang,iolist_size, &lt;br /&gt;[[...]]}, &lt;br /&gt;{mochiweb_request,respond,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;}, &lt;br /&gt;{rest_server_web,loop,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}, &lt;br /&gt;{mochiweb_http,headers,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;}, &lt;br /&gt;{proc_lib,init_p_do_apply,&lt;span style="color: #800080;"&gt;3&lt;/span&gt;}]&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;提问者遇到这个异常后判断是文档超长造成的，bob在下面的回复首先否定了这个猜测，并把关注点放在了trace信息中明确提示出来的iolist异常上面，他的回复：&lt;br /&gt; &lt;br /&gt;I don't think it has anything to do with the size of your document, &lt;br /&gt; &lt;br /&gt;your code is somehow returning a value that is not an iolist. Perhaps there is an atom in there, or an integer outside of 0..255 (I guess this is more likely, I don't know xmerl output very well). &lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;gt; iolist_size([&lt;span style="color: #800080;"&gt;256&lt;/span&gt;]). &lt;br /&gt;** exception &lt;span style="color: #008080;"&gt;error:&lt;/span&gt; bad argument &lt;br /&gt;&lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; function iolist_size/&lt;span style="color: #800080;"&gt;1&lt;/span&gt; &lt;br /&gt;called as iolist_size([&lt;span style="color: #800080;"&gt;256&lt;/span&gt;])&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;You probably want UTF-8, so unicode:characters_to_binary(xmerl:export_simple(Res,xmerl_xml)) is my&amp;nbsp;&lt;/p&gt;&#xD;
&lt;p&gt;guess at what you really want to be doing for the output.&lt;/p&gt;&#xD;
&lt;p&gt;-bob&lt;/p&gt;&#xD;
&lt;p&gt;详情点击：http://groups.google.com/group/mochiweb/browse_thread/thread/f67abc113b338bfe?pli=1&lt;/p&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div&gt;&lt;span&gt;按照这个提示给芒果，果然就把问题解决掉了；问题到这里还不能结束，追问一下，Erlang的List和IOList有什么区别？&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;&lt;strong&gt;iolist定义&lt;/strong&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;在erlang官方文档中iolist描述甚少,不过还是可以找到定义:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;pre&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;iolist()     maybe_improper_list(char() | binary() | iolist(), binary() | [])&lt;br /&gt;maybe_improper_list()     maybe_improper_list(any(), any())&lt;br /&gt;byte()     0..255&lt;br /&gt;char()     0..16#10ffffmaybe_improper_list(T)     maybe_improper_list(T, any())&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;pre&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;注意iolist相关的两个函数,他们接收的参数还可以是binary&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;pre&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;iolist_size(Item) -&amp;gt; integer() &amp;gt;= 0&lt;br /&gt;&lt;br /&gt;Types:Item = iolist() | &lt;span style="color: #ff0000;"&gt;binary()&lt;/span&gt; &lt;br /&gt;&lt;br /&gt;iolist_to_binary(IoListOrBinary) -&amp;gt; binary()&lt;br /&gt;&lt;br /&gt;Types:IoListOrBinary = iolist() | &lt;span style="color: #ff0000;"&gt;binary()&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;pre&gt;&lt;/pre&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;官方文档地址:&lt;/span&gt;&lt;a href="http://www.erlang.org/doc/reference_manual/typespec.html" target="_blank"&gt;http://www.erlang.org/doc/reference_manual/typespec.html&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div&gt;&lt;span&gt;我们动手测试一下:&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;Eshell V5.&lt;span style="color: #800080;"&gt;9&lt;/span&gt;  (abort with ^G)&lt;br /&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;gt; iolist_size([]).&lt;br /&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;gt; iolist_size([&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;anc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;]).&lt;br /&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&amp;gt; iolist_size([&lt;span style="color: #800080;"&gt;12&lt;/span&gt;,&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;anc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;]).&lt;br /&gt;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&amp;gt; iolist_size([&lt;span style="color: #800080;"&gt;12&lt;/span&gt;,&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;anc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;,&lt;span style="color: #800080;"&gt;23&lt;/span&gt;]).&lt;br /&gt;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;&amp;gt; iolist_size([&lt;span style="color: #800080;"&gt;12&lt;/span&gt;,&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;anc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;,&lt;span style="color: #800080;"&gt;23&lt;/span&gt;,&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;king&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;]).&lt;br /&gt;&lt;span style="color: #800080;"&gt;9&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;6&lt;/span&gt;&amp;gt; iolist_size([&lt;span style="color: #800080;"&gt;12&lt;/span&gt;,&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;anc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;,&lt;span style="color: #800080;"&gt;23&lt;/span&gt;,&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;king&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;,[&lt;span style="color: #800080;"&gt;23&lt;/span&gt;,&lt;span style="color: #800080;"&gt;34&lt;/span&gt;,&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;]]).&lt;br /&gt;&lt;span style="color: #800080;"&gt;15&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;7&lt;/span&gt;&amp;gt; iolist_size(&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;abc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;).&lt;br /&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;8&lt;/span&gt;&amp;gt; iolist_size(&amp;lt;&amp;lt;&amp;gt;&amp;gt;).&lt;br /&gt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;9&lt;/span&gt;&amp;gt; iolist_size([&lt;span style="color: #800080;"&gt;1234&lt;/span&gt;]).&lt;br /&gt;** exception &lt;span style="color: #008080;"&gt;error:&lt;/span&gt; bad argument&lt;br /&gt;     &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; function  iolist_size/&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;br /&gt;        called as iolist_size([&lt;span style="color: #800080;"&gt;1234&lt;/span&gt;])&lt;br /&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&amp;gt; iolist_size([&amp;lt;&amp;lt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;:&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;gt;&amp;gt;]).&lt;br /&gt;** exception &lt;span style="color: #008080;"&gt;error:&lt;/span&gt; bad argument&lt;br /&gt;     &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; function  iolist_size/&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;br /&gt;        called as iolist_size([&amp;lt;&amp;lt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;:&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;gt;&amp;gt;])&lt;br /&gt;&lt;span style="color: #800080;"&gt;11&lt;/span&gt;&amp;gt; iolist_size( [&lt;span style="color: #800080;"&gt;12&lt;/span&gt;,&lt;span style="color: #800080;"&gt;23&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;abc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&amp;lt;&amp;lt;abc&amp;gt;&amp;gt;]).&lt;br /&gt;** exception &lt;span style="color: #008080;"&gt;error:&lt;/span&gt; bad argument&lt;br /&gt;&lt;span style="color: #800080;"&gt;12&lt;/span&gt;&amp;gt; iolist_size( [&lt;span style="color: #800080;"&gt;12&lt;/span&gt;,&lt;span style="color: #800080;"&gt;23&lt;/span&gt;,&amp;lt;&amp;lt;abc&amp;gt;&amp;gt;]).&lt;br /&gt;** exception &lt;span style="color: #008080;"&gt;error:&lt;/span&gt; bad argument&lt;br /&gt;&lt;span style="color: #800080;"&gt;13&lt;/span&gt;&amp;gt; iolist_size( [&lt;span style="color: #800080;"&gt;12&lt;/span&gt;,&lt;span style="color: #800080;"&gt;23&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;abc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;abc&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;]).&lt;br /&gt;&lt;span style="color: #800080;"&gt;8&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;14&lt;/span&gt;&amp;gt;  L=[$H, $e, [$l, &amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;lo&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;, &lt;span style="color: #800000;"&gt;"&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;], [[[&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;W&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;o&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;], &amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;rl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;]] | [&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;d&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;]].&lt;br /&gt;[&lt;span style="color: #800080;"&gt;72&lt;/span&gt;,&lt;span style="color: #800080;"&gt;101&lt;/span&gt;,[&lt;span style="color: #800080;"&gt;108&lt;/span&gt;,&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;lo&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;],[[[&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;W&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;o&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;],&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;rl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;]],&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;d&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;]&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&#xD;
&lt;div&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;&lt;strong&gt;iolist适用的场景?&lt;/strong&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;首先能够找到的是mryufeng的这篇《iolist跟list有什么区别？》&amp;nbsp;&lt;a href="http://mryufeng.iteye.com/blog/634867" target="_blank"&gt;http://mryufeng.iteye.com/blog/634867&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;这篇文章分析源码得到了iolist数据结构的定义,并在解释了iolist的作用:&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span style="background-color: #ffff99;"&gt;Iolist的作用是用于往port送数据的时候.由于底层的系统调用如writev支持向量写, 就避免了无谓的iolist_to_binary这样的扁平话操作, 避免了内存拷贝,极大的提高了效率.建议多用.&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;这个是什么意思呢? 在Learn you some Erlang站点上&amp;lt;&amp;lt;&lt;a href="http://learnyousomeerlang.com/buckets-of-sockets" target="_blank"&gt;Buckets of Sockets&lt;/a&gt;&amp;gt;&amp;gt;一文的开篇我找到了答案:&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;div&gt;&lt;span&gt;A = [a]&lt;br /&gt;&#xD;
B = [b|A] = [b,a]&lt;br /&gt;&#xD;
C = [c|B] = [c,b,a]&lt;br /&gt;&#xD;
In the case of prepending, as above, whatever is held into A or B or C never needs to be rewritten. The representation of C can be seen as either [c,b,a], [c|B] or [c,|[b|[a]]], among others. In the last case, you can see that the shape of A is the same at the end of the list as when it was declared. Similarly for B. Here's how it looks with appending:&lt;br /&gt;&lt;br /&gt;&#xD;
A = [a]&lt;br /&gt;&#xD;
B = A ++ [b] = [a] ++ [b] = [a|[b]]&lt;br /&gt;&#xD;
C = B ++ [c] = [a|[b]] ++ [c] = [a|[b|[c]]]&lt;br /&gt;&#xD;
Do you see all that rewriting? When we create B, we have to rewrite A. When we write C, we have to rewrite B (including the [a|...] part it contains). If we were to add D in a similar manner, we would need to rewrite C. Over long strings, this becomes way too inefficient, and it creates a lot of garbage left to be cleaned up by the Erlang VM.&lt;br /&gt;&lt;br /&gt;&#xD;
With binaries, things are not exactly as bad:&lt;br /&gt;&lt;br /&gt;&#xD;
A = &amp;lt;&amp;lt;"a"&amp;gt;&amp;gt;&lt;br /&gt;&#xD;
B = &amp;lt;&amp;lt;A/binary, "b"&amp;gt;&amp;gt; = &amp;lt;&amp;lt;"ab"&amp;gt;&amp;gt;&lt;br /&gt;&#xD;
C = &amp;lt;&amp;lt;B/binary, "c"&amp;gt;&amp;gt; = &amp;lt;&amp;lt;"abc"&amp;gt;&amp;gt;&lt;br /&gt;&#xD;
In this case, binaries know their own length and data can be joined in constant time. That's good, much better than lists. They're also more compact. For these reasons, we'll often try to stick to binaries when using text in the future.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;There are a few downsides, however. Binaries were meant to handle things in certain ways, and there is still a cost to modifying binaries, splitting them, etc. Moreover, sometimes we'll work with code that uses strings, binaries, and individual characters interchangeably. Constantly converting between types would be a hassle.&lt;br /&gt;&lt;br /&gt;&#xD;
In these cases, IO lists are our saviour. IO lists are a weird type of data structure. They are lists of either bytes (integers from 0 to 255), binaries, or other IO lists. This means that functions that accept IO lists can accept items such as [$H, $e, [$l, &amp;lt;&amp;lt;"lo"&amp;gt;&amp;gt;, " "], [[["W","o"], &amp;lt;&amp;lt;"rl"&amp;gt;&amp;gt;]] | [&amp;lt;&amp;lt;"d"&amp;gt;&amp;gt;]]. When this happens, the Erlang VM will just flatten the list as it needs to do it to obtain the sequence of characters Hello World.&lt;br /&gt;&lt;br /&gt;&#xD;
What are the functions that accept such IO Lists? Most of the functions that have to do with outputting data do. Any function from the io module, file module, TCP and UDP sockets will be able to handle them. Some library functions, such as some coming from the unicode module and all of the functions from the re (for regular expressions) module will also handle them, to name a few.&lt;br /&gt;&lt;br /&gt;&#xD;
Try the previous Hello World IO List in the shell with io:format("~s~n", [IoList]) just to see. It should work without a problem.&lt;br /&gt;&lt;br /&gt;&#xD;
All in all, they're a pretty clever way of building strings to avoid the problems of immutable data structures when it comes to dynamically building content to be output.&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div&gt;&lt;span&gt;简单说明一下上面的内容:&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;|-&amp;gt;如果是在List头部追加内容是非常快速的,但是在List尾部追加内容就要进行遍历&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&amp;nbsp;-&amp;gt; 使用binary数据可以在常量时间内完成尾部追加,但是问题:①修改和split存在消耗 ;②字符和二进制数据的常量转换&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;-&amp;gt;&lt;span&gt;&amp;nbsp;iolist对这种数据混搭有一个较好的支持,Erlang VM会将list平铺,可以使用io:format来检验各种数据构成的iolist输出之后的结果&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;-&amp;gt; 总结 iolist是单次赋值约束下,动态构建字符串内容输出的好方法;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div&gt;&lt;span&gt;我们可以通过erlc +\'to_core\' M.erl 的方法(参见:&lt;a href="http://www.cnblogs.com/me-sa/archive/2012/01/09/erlang0029.html" target="_blank"&gt;[Erlang 0029] Erlang Inline编译&lt;/a&gt;)查看一下iolist的&lt;span&gt;&amp;nbsp;&lt;/span&gt;Core Erlang表示:&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;在Core Erlang中List = [1,2,3,4,5,6,7,8,9],会被表示为:[1|[2|[3|[4|[5|[6|[7|[8|[9]]]]]]]]]&lt;/div&gt;&#xD;
&lt;div&gt;看下&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;L=[$H, $e, [$l, &amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;lo&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;, &lt;span style="color: #800000;"&gt;"&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;], [[[&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;W&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;o&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;], &amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;rl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;]] | [&amp;lt;&amp;lt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;d&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&amp;gt;&amp;gt;]],&lt;br /&gt;  iolist_size(L)&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;转换为:&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;do  %% Line &lt;span style="color: #800080;"&gt;14&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff;"&gt;call&lt;/span&gt; &lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;erlang&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;:&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;iolist_size&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;br /&gt;                ([&lt;span style="color: #800080;"&gt;72&lt;/span&gt;|[&lt;span style="color: #800080;"&gt;101&lt;/span&gt;|[[&lt;span style="color: #800080;"&gt;108&lt;/span&gt;|[#{#&amp;lt;&lt;span style="color: #800080;"&gt;108&lt;/span&gt;&amp;gt;(&lt;span style="color: #800080;"&gt;8&lt;/span&gt;,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;integer&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,[&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;unsigned&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;|[&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;big&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;]]),&lt;br /&gt;                                   #&amp;lt;&lt;span style="color: #800080;"&gt;111&lt;/span&gt;&amp;gt;(&lt;span style="color: #800080;"&gt;8&lt;/span&gt;,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;integer&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,[&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;unsigned&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;|[&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;big&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;]])}#|[[&lt;span style="color: #800080;"&gt;32&lt;/span&gt;]]]]|[[[[[&lt;span style="color: #800080;"&gt;87&lt;/span&gt;]|[[&lt;span style="color: #800080;"&gt;111&lt;/span&gt;]]]|[#{#&amp;lt;&lt;span style="color: #800080;"&gt;114&lt;/span&gt;&amp;gt;(&lt;span style="color: #800080;"&gt;8&lt;/span&gt;,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;integer&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,[&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;unsigned&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;|[&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;big&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;]]),&lt;br /&gt;                                                                                                              #&amp;lt;&lt;span style="color: #800080;"&gt;108&lt;/span&gt;&amp;gt;(&lt;span style="color: #800080;"&gt;8&lt;/span&gt;,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;integer&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,[&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;unsigned&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;|[&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;big&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;]])}#]]]|[#{#&amp;lt;&lt;span style="color: #800080;"&gt;100&lt;/span&gt;&amp;gt;(&lt;span style="color: #800080;"&gt;8&lt;/span&gt;,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;integer&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,[&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;unsigned&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;|[&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;big&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;]])}#]]]]])&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;相关阅读&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;Stackoverflow上有人提到了&lt;a href="http://stackoverflow.com/questions/1063497/hidden-features-of-erlanghttp://stackoverflow.com/questions/1063497/hidden-features-of-erlang" target="_blank"&gt;同样的问题&lt;/a&gt;:&lt;/p&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;p&gt;Ports, external or linked-in, accept something called io-lists for sending data to them. An io-list is a binary or a (possibly deep) list of binaries or integers in the range 0..255.&lt;br /&gt;This means that rather than concatenating two lists before sending them to a port, one can just send them as two items in a list. So instead of&lt;br /&gt;"foo" ++ "bar"&lt;br /&gt;one do&lt;br /&gt;["foo", "bar"]&lt;br /&gt;In this example it is of course of miniscule difference. But the iolist in itself allows for convenient programming when creating output data. io_lib:format/2,3 itself returns an io list for example.&lt;br /&gt;The function erlang:list_to_binary/1 accepts io lists, but now we have erlang:iolist_to_binary/1 which convey the intention better. There is also an erlang:iolist_size/1.&lt;br /&gt;Best of all, since files and sockets are implemented as ports, you can send iolists to them. No need to flatten or append.&lt;/p&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;还有这一篇:&lt;strong&gt;A Ramble Through Erlang IO Lists&amp;nbsp;&lt;a href="http://prog21.dadgum.com/70.html"&gt;http://prog21.dadgum.com/70.html&lt;/a&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;span&gt;The IO List is a handy data type in Erlang, but not one that's often discussed in tutorials. It's any binary. Or any list containing integers between 0 and 255. Or any arbitrarily nested list containing either of those two things. Like this:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&#xD;
&lt;div &gt;[10, 20, "hello", &amp;lt;&amp;lt;"hello",65&amp;gt;&amp;gt;, [&amp;lt;&amp;lt;1,2,3&amp;gt;&amp;gt;, 0, 255]]&lt;/div&gt;&#xD;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&#xD;
&lt;span&gt;The key to IO lists is that you never flatten them. They get passed directly into low-level runtime functions (such as&amp;nbsp;&lt;/span&gt;&lt;tt&gt;file:write_file&lt;/tt&gt;&lt;span&gt;), and the flattening happens without eating up any space in your Erlang process. Take advantage of that! Instead of appending values to lists, use nesting instead. For example, here's a function to put a string in quotes:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&#xD;
&lt;div &gt;quote(String) -&amp;gt; $" ++ String ++ $".&lt;/div&gt;&#xD;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&#xD;
&lt;span&gt;If you're working with IO lists, you can avoid the append operations completely (and the second "++" above results in an entirely new version of&amp;nbsp;&lt;/span&gt;&lt;tt&gt;String&lt;/tt&gt;&lt;span&gt;&amp;nbsp;being created). This version uses nesting instead:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&#xD;
&lt;div &gt;quote(String) -&amp;gt; [$", String, $"].&lt;/div&gt;&#xD;
&lt;span&gt;&lt;span&gt;&lt;span&gt;&#xD;
&lt;span&gt;This creates three list elements no matter how long the initial string is. The first version creates&amp;nbsp;&lt;/span&gt;&lt;tt&gt;length(String) + 2&lt;/tt&gt;&lt;span&gt;&amp;nbsp;elements. It's also easy to go backward and un-quote the string: just take the second list element. Once you get used to nesting you can avoid most append operations completely.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;One thing that nested list trick is handy for is manipulating filenames. Want to add a directory name and ".png" extension to a filename? Just do this:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&#xD;
&lt;div &gt;[Directory, $/, Filename, ".png"]&lt;/div&gt;&#xD;
&lt;span&gt;&lt;span&gt;&#xD;
&lt;span&gt;Unfortunately, filenames in the&amp;nbsp;&lt;/span&gt;&lt;tt&gt;file&lt;/tt&gt;&lt;span&gt;&amp;nbsp;module are not true IO lists. You can pass in deep lists, but they get flattened by an Erlang function (&lt;/span&gt;&lt;tt&gt;file:file_name/1&lt;/tt&gt;&lt;span&gt;), not the runtime system. That means you can still dodge appending lists in your own code, but things aren't as efficient behind the scenes as they could be. And "deep lists" in this case means&lt;/span&gt;&lt;em&gt;only&lt;/em&gt;&lt;span&gt;&amp;nbsp;lists, not binaries. Strangely, these deep lists can also contain atoms, which get expanded via&amp;nbsp;&lt;/span&gt;&lt;tt&gt;atom_to_list&lt;/tt&gt;&lt;span&gt;.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span&gt;Ideally filenames would be IO lists, but for compatibility reasons there's still the need to support atoms in filenames. That brings up an interesting idea: why not allow atoms as part of the general IO list specification? It makes sense, as the runtime system has access to the atom table, and there's a simple correspondence between an atom and how it gets encoded in a binary; 'atom' is treated the same as "atom". I find I'm often calling&amp;nbsp;&lt;/span&gt;&lt;tt&gt;atom_to_list&lt;/tt&gt;&lt;span&gt;&amp;nbsp;before sending data to external ports, and that would no longer be necessary.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;总结&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&amp;nbsp; iolist是单次赋值约束下,避免了字符串和二进制数据的转换,是动态构建字符串内容输出的好方法;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&lt;img src="http://www.cnblogs.com/me-sa/aggbug/2333842.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2012/01/31/erlang0034.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/me-sa/archive/2012/01/18/erlang0033.html</id><title type="text">[Erlang 0033] 接入Erlang控制台的几种方法</title><summary type="text">Erlang服务部署在生产环境也需要一些方式进入到Erlang控制台来做一些工作,"就像魔术师的飞刀,出手但并没有脱手".</summary><published>2012-01-18T07:03:00Z</published><updated>2012-01-18T07:03:00Z</updated><author><name>坚强2002</name><uri>http://www.cnblogs.com/me-sa/</uri></author><link rel="alternate" href="http://www.cnblogs.com/me-sa/archive/2012/01/18/erlang0033.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/me-sa/archive/2012/01/18/erlang0033.html"/><content type="html">&lt;p&gt;在window中调试的时候我们可以通过启动多个cmd窗口运行Erlang节点,在生产环境中我们需要Erlang服务在Centos服务器上后台运行;这就需要在启动的时候添加启动参数detached来脱离终端:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;-detached&lt;/strong&gt; Starts the Erlang runtime system detached from the system console. Useful for running daemons and backgrounds processes. Implies -noinput.&lt;/p&gt;&#xD;
&lt;p&gt;对于我们自己的服务,即使部署到了生产环境一定要做到"像魔术师的飞刀,出手但并没有脱手",还是需要一些方式进入到Erlang后台进程来做一些工作比如:查看某一个Erlang节点的运行时信息(内存,进程数等),让服务优雅的退出而不是kill进程,或者做一下热更新(参见:&lt;a href="http://www.cnblogs.com/me-sa/archive/2011/10/29/erlang0010.html"&gt;[Erlang 0010] Erlang 热更新&lt;/a&gt;&amp;nbsp;当然热更新可以使用reloader.erl的方案来简化);一开始的时候服务器比较少,我们采用的是JCL的方式去处理的;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;Erlang Shell JCL&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;JCL是Erlang Shell的一种运行模式,即Job Control Mode (JCL, in which jobs can be started, killed, detached and connected).我们启动两个节点来完成这个操作;&lt;br /&gt;&lt;strong&gt;Node_1&lt;/strong&gt; 添加了-detached选项,启动之后直接在后台运行并没有启动Shell&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;erl -setcookie abc -name node_1@192.168.1.123 -detached&lt;/span&gt; &lt;br /&gt;&lt;strong&gt;Node_2&lt;/strong&gt; 使用了和Node_1相同的cookie,启动之后进入Erlang Shell界面&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;erl -setcookie abc -name node_2@192.168.1.123&lt;/span&gt;&lt;br /&gt;下面我们开始在node_2@192.168.1.123演练JCL:&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;Eshell V5.&lt;span style="color: #800080;"&gt;9&lt;/span&gt;  (abort with ^G)&lt;br /&gt;(node_2@192.&lt;span style="color: #800080;"&gt;168&lt;/span&gt;.&lt;span style="color: #800080;"&gt;1&lt;/span&gt;.&lt;span style="color: #800080;"&gt;123&lt;/span&gt;)&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;gt; node().    %当前这是在node_2&lt;br /&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;node_2@192.168.1.123&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;br /&gt;(node_2@192.&lt;span style="color: #800080;"&gt;168&lt;/span&gt;.&lt;span style="color: #800080;"&gt;1&lt;/span&gt;.&lt;span style="color: #800080;"&gt;123&lt;/span&gt;)&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;gt;                %Control + G 进入JCL模式&lt;br /&gt;User switch command&lt;br /&gt;--&amp;gt; h  &lt;br /&gt;  c [nn]            - connect to job&lt;br /&gt;  i [nn]            - interrupt job&lt;br /&gt;  k [nn]            - kill job&lt;br /&gt;  j                 - list all jobs&lt;br /&gt;  s [shell]         - start local shell&lt;br /&gt;  r [node [shell]]  - start remote shell&lt;br /&gt;  q        - quit erlang&lt;br /&gt;  ? | h             - this message&lt;br /&gt;--&amp;gt; r&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;node_1@192.168.1.123&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;                           %尝试连接到node_1@192.&lt;span style="color: #800080;"&gt;168&lt;/span&gt;.&lt;span style="color: #800080;"&gt;1&lt;/span&gt;.&lt;span style="color: #800080;"&gt;123&lt;/span&gt;  &lt;br /&gt;--&amp;gt; j&lt;br /&gt;   &lt;span style="color: #800080;"&gt;1&lt;/span&gt;  {shell,start,[init]}                                          %列出所有的Job&lt;br /&gt;   &lt;span style="color: #800080;"&gt;2&lt;/span&gt;* {&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;node_1@192.168.1.123&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,shell,start,[]}&lt;br /&gt;--&amp;gt; c &lt;span style="color: #800080;"&gt;2&lt;/span&gt;                                                               %这里2是job的编号,切换到job &lt;span style="color: #800080;"&gt;2&lt;/span&gt; &lt;br /&gt;Eshell V5.&lt;span style="color: #800080;"&gt;9&lt;/span&gt;  (abort with ^G)&lt;br /&gt;(node_1@192.&lt;span style="color: #800080;"&gt;168&lt;/span&gt;.&lt;span style="color: #800080;"&gt;1&lt;/span&gt;.&lt;span style="color: #800080;"&gt;123&lt;/span&gt;)&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;gt; node().                %注意提示符,现在已经是在node_1&lt;br /&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;node_1@192.168.1.123&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;br /&gt;(node_1@192.&lt;span style="color: #800080;"&gt;168&lt;/span&gt;.&lt;span style="color: #800080;"&gt;1&lt;/span&gt;.&lt;span style="color: #800080;"&gt;123&lt;/span&gt;)&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;gt; &lt;span style="color: #008080;"&gt;erlang:&lt;/span&gt;now().&lt;br /&gt;{&lt;span style="color: #800080;"&gt;1326&lt;/span&gt;,&lt;span style="color: #800080;"&gt;801888&lt;/span&gt;,&lt;span style="color: #800080;"&gt;347570&lt;/span&gt;}&lt;br /&gt;(node_1@192.&lt;span style="color: #800080;"&gt;168&lt;/span&gt;.&lt;span style="color: #800080;"&gt;1&lt;/span&gt;.&lt;span style="color: #800080;"&gt;123&lt;/span&gt;)&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&amp;gt;                             %再一次Control + G&lt;br /&gt;User switch command                                   &lt;br /&gt;--&amp;gt; j                                                                   &lt;br /&gt;   &lt;span style="color: #800080;"&gt;1&lt;/span&gt;  {shell,start,[init]}&lt;br /&gt;   &lt;span style="color: #800080;"&gt;2&lt;/span&gt;* {&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;node_1@192.168.1.123&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,shell,start,[]}&lt;br /&gt;--&amp;gt; c &lt;span style="color: #800080;"&gt;1&lt;/span&gt;                                                               %切换到job &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;br /&gt;(node_2@192.&lt;span style="color: #800080;"&gt;168&lt;/span&gt;.&lt;span style="color: #800080;"&gt;1&lt;/span&gt;.&lt;span style="color: #800080;"&gt;123&lt;/span&gt;)&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;gt; node().                %注意提示符,我们已经回到了node_2&lt;br /&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;node_2@192.168.1.123&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;br /&gt;(node_2@192.&lt;span style="color: #800080;"&gt;168&lt;/span&gt;.&lt;span style="color: #800080;"&gt;1&lt;/span&gt;.&lt;span style="color: #800080;"&gt;123&lt;/span&gt;)&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&amp;gt; &lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;这样来来回回切换是不是有点盗梦空间的意思?是不是可以更简单一点,比如直接进入node_1呢?借助&lt;strong&gt;-remsh&lt;/strong&gt;参数就可以做到&lt;/p&gt;&#xD;
&lt;p&gt;看看-remsh的说明恰好是我们需要的:&lt;/p&gt;&#xD;
&lt;p&gt;If you want an Erlang node to have a remote job active from the start (rather than the default local job), you start Erlang with the -remsh flag. Example: erl -sname this_node -remsh other_node@other_host&lt;/p&gt;&#xD;
&lt;p&gt;动手试一下:&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;erl -setcookie abc -name node_3@192.168.1.123 -remsh node_1@192.168.1.123 %%这样就直接进入了node_1节点&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;注意&lt;/strong&gt;:&lt;strong&gt;直接进入到了node_1,执行完操作了想要退出怎么办?&lt;/strong&gt; 你要是在这里执行一下q(). node_1这个节点就直接死掉了;&lt;br /&gt; 正确的方法还是Ctrl+G进入JCL模式然后执行q命令退出;使用ps aux|grep node查看一下进程是不是还在&lt;/p&gt;&#xD;
&lt;p&gt;ejabberd网站上提到了这个方法 &lt;br /&gt;[1] Attach an Erlang Shell to an Already Running ejabberd Process http://www.ejabberd.im/tricks&lt;br /&gt;[2] Interconnecting Erlang Nodes http://www.ejabberd.im/interconnect-erl-nodes&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&amp;nbsp;&lt;span&gt;另一种实用的接入erlang控制台的方法&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span&gt;地址:http://mryufeng.iteye.com/blog/362394 &amp;nbsp;&lt;strong&gt;Powered by&amp;nbsp;mryufeng&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;按照mryufeng老大的方法操练了一番,成功,中间 /usr/local/lib/erlang/bin/start 启动失败,同样是目录和配置文件缺失的问题&lt;br /&gt;mkdir /usr/local/lib/erlang/log&lt;br /&gt;echo "[]." &amp;gt; /usr/local/lib/erlang/releases/R15B/sys.config&lt;/p&gt;&#xD;
&lt;p&gt;Stackoverflow的相关问题: How to create deamon program with erlang? http://stackoverflow.com/questions/5972811/how-to-create-deamon-program-with-erlang&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span&gt;原理见下图:&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/17329/2012011814522917.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;erl_call&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;div&gt;&lt;span&gt;&amp;nbsp; 随着服务器增多,登录一台台服务器然后使用JCL去做热更新之类的就有点麻烦了,取而代之的解决方案就是ssh登录到每台服务器然后向该服务器上的Erlang节点发送消息,执行热更新(当然不限于热更新了);&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&amp;nbsp; 这里有一个很强大的工具可以用:erl_call;&lt;span&gt;erl_call模块的设计目标就是使用Unix Shell脚本与分布式Erlang节点进行交互,&lt;/span&gt;&lt;span&gt;erl_call可以启动或者连接到一个分布式的Erlang节点进行简单的方法调用甚至执行表达式序列;erl_call构建在erl_interface之上,通过标准的RPC调用方式与Erlang的rex server交互,并不需要额外的工具支持.注意Erlang节点的RPC服务启动的时候注册的名字是rex http://www.google.com/codesearch#dNzC48WMK6w/lib/kernel/src/rpc.erl&amp;amp;q=rpc%20lang:erlang&amp;amp;type=cs&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;看一下erl_call的帮助,注意Erlang版本不同erl_call的路径也有所不同:&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;div&gt;Usage: /usr/local/lib/erlang/lib/erl_interface-3.7.6/bin/erl_call [-[demqrsv]] [-c Cookie] [-h HiddenName]&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; [-x ErlScript] [-a [Mod [Fun [Args]]]]&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (-n Node | -sname Node | -name Node)&lt;br /&gt;&lt;br /&gt; &amp;nbsp; where: -a&amp;nbsp; apply(Mod,Fun,Args) (e.g -a 'erlang length [[a,b,c]]'&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -c&amp;nbsp; cookie string; by default read from ~/.erlang.cookie&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -d&amp;nbsp; direct Erlang output to ~/.erl_call.out.&amp;lt;Nodename&amp;gt;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -e&amp;nbsp; evaluate contents of standard input (e.g echo "X=1,Y=2,{X,Y}."|erl_call -e ...)&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -h&amp;nbsp; specify a name for the erl_call client node&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -m&amp;nbsp; read and compile Erlang module from stdin&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -n&amp;nbsp; name of Erlang node, same as -name&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -name&amp;nbsp; name of Erlang node, expanded to a fully qualified&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -sname name of Erlang node, short form will be used&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -q&amp;nbsp; halt the Erlang node (overrides the -s switch)&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -r&amp;nbsp; use a random name for the erl_call client node&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -s&amp;nbsp; start a new Erlang node if necessary&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -v&amp;nbsp; verbose mode, i.e print some information on stderr&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; -x&amp;nbsp; use specified erl start script, default is erl&lt;/div&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;div&gt;&lt;span&gt;简单翻译一下:&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;strong&gt;-a &amp;nbsp; &amp;nbsp;执行&lt;/strong&gt;&lt;span&gt;erlang:apply/3,需要提供的就是m f a,m是必须的,f默认值start,a默认值[],注意这个flag只接受一个参数,所以最好通过添加括号把&lt;/span&gt;&lt;span&gt;m f a&lt;/span&gt;&lt;span&gt;组织起来.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;-c 执行cookie值如果没有指定就会使用&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;span&gt;~/.erlang.cookie&lt;/span&gt;&lt;span&gt;&amp;nbsp;文件中定义的cookie,Erlang 节点之间通信必须要有相同的cookie&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;-d 调试模式;&lt;/strong&gt;所有的IO都会输出到&lt;span&gt;~/.erl_call.out.Nodename文件,其中NodeName就是我们要处理的erlang节点名;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;-e&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;读一系列的Erlang表达式并返回最后一个表达式的结果,这些表达式用','分隔,'.'结束,这个Erlang Shell是一致的,&lt;span&gt;Control-D组合键结束输入,&lt;/span&gt;如果成功返回结果{ok,Result}.&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;-h&amp;nbsp;&lt;/strong&gt;HiddenName&amp;nbsp;隐藏erl_call代表的节点&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;-m&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/strong&gt;读入并编译一个module&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;-n&amp;nbsp;&lt;/strong&gt;&lt;strong&gt;-name&amp;nbsp;&lt;/strong&gt;&lt;strong&gt;-sname&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/strong&gt;这三个参数三选一,name和n是同样的含义是为了兼容依然保留,sname代码短名称&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;-q&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/strong&gt;停止Erlang 节点&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;-r&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/strong&gt;为erl_call生一个随机name&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;-s&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/strong&gt;必要的话启动一个Erlang的分布式节点,意思是自由第一个调用会启动一个Erlang节点后续的调用就会快很多.&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;-v&amp;nbsp;&lt;/strong&gt;&lt;span&gt;&amp;nbsp;多打印一些冗余信息&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;-x ErlScript&lt;/strong&gt;&lt;span&gt;:指定Erlang启动脚本如果不指定就是用erl start-up脚本&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;比如我们现在要获取节点node_1的内存信息&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff;"&gt;/usr/local/lib/erlang/lib/erl_interface-3.7.6/bin/erl_call -s -a 'erlang memory ' -name node_1@192.168.1.123 -c abc&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;实践中遇到两个问题:&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;问题一&lt;/strong&gt;:当name里面包含ip地址的时候执行会报错,这个erlang论坛里面有人也提到了:&lt;/div&gt;&#xD;
&lt;div&gt;erl_call can now use an IP address for remote node name&amp;nbsp;&lt;a href="http://erlang.org/pipermail/erlang-patches/2010-October/001533.html"&gt;http://erlang.org/pipermail/erlang-patches/2010-October/001533.html&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div&gt;erl_call: remove get_hostent&amp;nbsp;&lt;a href="http://erlang.org/pipermail/erlang-patches/2010-October/001550.html"&gt;http://erlang.org/pipermail/erlang-patches/2010-October/001550.html&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div&gt;我的解决方案就是把name换成了sname并去掉了ip地址就OK了;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;问题二&lt;/strong&gt;:在使用-e参数的时候怎么结束掉输入并查看结果&lt;/div&gt;&#xD;
&lt;div&gt;这个问题的确挺二的,就因为没有仔细阅读文档,结束的时候需要用Ctrl+D,&lt;a href="http://www.erlang.org/doc/man/erl_call.html"&gt;http://www.erlang.org/doc/man/erl_call.html&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span style="color: #0000ff;"&gt;/usr/local/lib/erlang/lib/erl_interface-3.7.6/bin/erl_call -e -name node_1@192.168.1.123 -c abc&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;A=1,&lt;br /&gt;&#xD;
B=2,&lt;br /&gt;&#xD;
C=A+B.&lt;br /&gt;&#xD;
%Ctrl + D&amp;nbsp;&lt;br /&gt;&#xD;
{ok, 3}&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;有了这些方法,我们可以方便的了解和控制运行中的Erlang节点,洋溢着幸福感啊!&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;各位春节快乐!!!&lt;/div&gt;&lt;img src="http://www.cnblogs.com/me-sa/aggbug/2325603.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2012/01/18/erlang0033.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/me-sa/archive/2012/01/12/erlang0032.html</id><title type="text">[Erlang 0032] Erlang Binary的内部实现</title><summary type="text">The binary object can be referenced by any number of ProcBins from any number of processes; the object contains a reference counter to keep track of the number of references, so that it can be removed when the last reference disappears.</summary><published>2012-01-11T16:13:00Z</published><updated>2012-01-11T16:13:00Z</updated><author><name>坚强2002</name><uri>http://www.cnblogs.com/me-sa/</uri></author><link rel="alternate" href="http://www.cnblogs.com/me-sa/archive/2012/01/12/erlang0032.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/me-sa/archive/2012/01/12/erlang0032.html"/><content type="html">&lt;div&gt;&lt;span&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2011/11/13/erlang0014.html"&gt;[Erlang 0014]Erlang垃圾回收机制&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2011/12/25/erlang0024.html"&gt;[Erlang 0024]Erlang二进制数据处理&lt;/a&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;上面两篇文章都提到了二进制数据相关的内容,今天阅读了一下官方文档中关于二进制实现的内容,整理笔记于此.先看一张图:&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/17329/2012011121215666.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;思维导图解释&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;binary和bitstring内部实现机制相同&lt;/li&gt;&#xD;
&lt;li&gt;Erlang内部有四种二进制类型,两种容器,两种引用&lt;/li&gt;&#xD;
&lt;li&gt;容器有refc binaries 和 heap binaries&lt;/li&gt;&#xD;
&lt;li&gt;refc binaries又可以分成两部分存放在进程堆(process heap)的ProcBin和进程堆以外的二进制对象&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span&gt;ProcBin包含一个二进制数据的元数据信息,包含了二进制数据的位置和引用计数&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;li&gt;游离在进程堆之外的二进制对象可以被任意数量的进程和任意数量的ProcBin引用,该对象包含了引用计数器,一旦计数器归零就可以移除掉&lt;/li&gt;&#xD;
&lt;li&gt;所有的ProcBin对象都是链表的一部分,所以GC跟踪它们并在ProcBin消失的时候将应用计数减一&lt;/li&gt;&#xD;
&lt;li&gt;heap binaries 都是小块二进制数据,最大64字节,直接存放在进程堆(process heap),垃圾回收和发送消息都是通过拷贝实现,不需要垃圾回收器做特殊处理&lt;/li&gt;&#xD;
&lt;li&gt;引用类型有两种:sub binaries , match contexts&lt;/li&gt;&#xD;
&lt;li&gt;sub binary是split_binary的时候产生的,sub binary是另外一个二进制数据的部分应用(refc 或者 heap binary),由于并没有数据拷贝所以binary的模式匹配成本相当低&lt;/li&gt;&#xD;
&lt;li&gt;match context类似sub binary,但是针对二进制匹配做了优化;例如它包含一个直接指向二进制数据的指针.从二进制匹配出来字段值之后移动指针位置即可.&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;p&gt;&lt;span&gt;官方文档链接:&lt;a href="http://www.erlang.org/doc/efficiency_guide/binaryhandling.html"&gt;http://www.erlang.org/doc/efficiency_guide/binaryhandling.html&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;p&gt;&lt;span&gt;&lt;span&gt;Internally, binaries and bitstrings are implemented in the same way.&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span&gt;There are four types of binary objects internally. Two of them are&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;strong&gt;containers&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;for binary data and two of them are&amp;nbsp;merely&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;strong&gt;references&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;to a part of a binary.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;The binary containers are called&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;strong&gt;refc binaries&amp;nbsp;&lt;/strong&gt;(short for reference-counted binaries) and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;strong&gt;heap binaries&lt;/strong&gt;.&lt;/div&gt;&#xD;
&lt;div&gt;Refc binaries consist of two parts: an object stored on the&lt;span&gt;&amp;nbsp;&lt;/span&gt;process heap, called a &lt;strong&gt;ProcBin&lt;/strong&gt;, and the&lt;strong&gt;&amp;nbsp;binary object&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;itself&amp;nbsp;stored outside all process heaps.The binary object can be referenced by any number of ProcBins from any number of processes; the object contains a&amp;nbsp;reference counter to keep track of the number of references, so that it can be removed when the last reference disappears.&lt;/div&gt;&#xD;
&lt;div&gt;All ProcBin objects in a process are part of a linked list, so that the garbage collector can keep track of them and&amp;nbsp;decrement the reference counters in the binary when a ProcBin disappears.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;Heap binaries&lt;/strong&gt; are&lt;span&gt;&amp;nbsp;&lt;/span&gt;small binaries,&lt;span&gt;&amp;nbsp;&lt;/span&gt;up&lt;span&gt;&amp;nbsp;&lt;/span&gt;to 64 bytes, that are stored directly on the process heap. They will be&lt;span&gt;&amp;nbsp;&lt;/span&gt;copied&amp;nbsp;when the process is garbage collected and when they are sent as a message. They don't require any special handling&amp;nbsp;by the garbage collector.&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&#xD;
&lt;div&gt;There are two types of reference objects that can reference part of a refc binary or heap binary. They are called&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;strong&gt;sub&amp;nbsp;binaries&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;and&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;strong&gt;match contexts.&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;&#xD;
&lt;div&gt;A sub binary is created by split_binary/2 and when a binary is matched out in a binary pattern. A sub binary&amp;nbsp;is a reference into a part of another binary (refc or heap binary, never into a another sub binary). Therefore, matching&amp;nbsp;out a binary is relatively cheap because the actual binary data is never copied.&lt;br /&gt; A match context is similar to a sub binary, but is optimized for binary matching; for instance, it contains a direct pointer&amp;nbsp;to the binary data. For each field that is matched out of a binary, the position in the match context will be incremented.&lt;/div&gt;&#xD;
&lt;/blockquote&gt;&lt;img src="http://www.cnblogs.com/me-sa/aggbug/2319894.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2012/01/12/erlang0032.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/me-sa/archive/2012/01/10/erlang0031.html</id><title type="text">[Erlang 0031] Erlang Shell中的输出完整数据</title><summary type="text">标准的解决方案是使用shell中的rp方法格式化输出结果 比如 rp(os:getenv()).</summary><published>2012-01-10T14:28:00Z</published><updated>2012-01-10T14:28:00Z</updated><author><name>坚强2002</name><uri>http://www.cnblogs.com/me-sa/</uri></author><link rel="alternate" href="http://www.cnblogs.com/me-sa/archive/2012/01/10/erlang0031.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/me-sa/archive/2012/01/10/erlang0031.html"/><content type="html">&lt;p&gt;前两天群里面有人问shell里面长数据被省略为 [...]|...],如何查看被省略的部分,他是在调用os:getenv()的时候遇到的这个问题,咱们前面也遇到过类似的问题,比如&lt;a href="http://www.cnblogs.com/me-sa/archive/2012/01/04/erlang0028.html"&gt; string:tokens(binary_to_list(erlang:system_info(info)),"\n").&lt;/a&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;Eshell V5.&lt;span style="color: #800080;"&gt;9&lt;/span&gt;  (abort with ^G)&lt;br /&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;gt;  &lt;span style="color: #008080;"&gt;string:&lt;/span&gt;tokens( binary_to_list(&lt;span style="color: #008080;"&gt;erlang:&lt;/span&gt;system_info(info)),&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).&lt;br /&gt;[&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=memory&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;total: 4331920&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;processes: 438877&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;processes_used: 438862&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;system: 3893043&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;atom: 146321&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;atom_used: 119102&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;binary: 327936&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;code: 1929551&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;ets: 123308&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=hash_table:atom_tab&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 4813&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;used: 3508&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;objs: 6410&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;depth: 7&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=index_table:atom_tab&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 7168&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;limit: 1048576&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;entries: 6410&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=hash_table:module_code&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 97&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;used: 52&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;objs: 72&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;depth: 4&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=index_table:module_code&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 1024&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;limit: 65536&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;entries: 72&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;[...]|...]&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;当时我在群里面给了一个不标准的解决方法:binary_to_list(list_to_binary(os:getenv())).这个很野的路子是以前调试代码的时候偶尔发现的;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&#xD;
标准的解决方案是使用shell中的rp方法格式化输出结果 比如 rp(os:getenv()).特此修正,抱歉&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #800080;"&gt;9&lt;/span&gt;&amp;gt; L=&lt;span style="color: #008080;"&gt;lists:&lt;/span&gt;seq(&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;100&lt;/span&gt;).&lt;br /&gt;[&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;,&lt;span style="color: #800080;"&gt;3&lt;/span&gt;,&lt;span style="color: #800080;"&gt;4&lt;/span&gt;,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;,&lt;span style="color: #800080;"&gt;6&lt;/span&gt;,&lt;span style="color: #800080;"&gt;7&lt;/span&gt;,&lt;span style="color: #800080;"&gt;8&lt;/span&gt;,&lt;span style="color: #800080;"&gt;9&lt;/span&gt;,&lt;span style="color: #800080;"&gt;10&lt;/span&gt;,&lt;span style="color: #800080;"&gt;11&lt;/span&gt;,&lt;span style="color: #800080;"&gt;12&lt;/span&gt;,&lt;span style="color: #800080;"&gt;13&lt;/span&gt;,&lt;span style="color: #800080;"&gt;14&lt;/span&gt;,&lt;span style="color: #800080;"&gt;15&lt;/span&gt;,&lt;span style="color: #800080;"&gt;16&lt;/span&gt;,&lt;span style="color: #800080;"&gt;17&lt;/span&gt;,&lt;span style="color: #800080;"&gt;18&lt;/span&gt;,&lt;span style="color: #800080;"&gt;19&lt;/span&gt;,&lt;span style="color: #800080;"&gt;20&lt;/span&gt;,&lt;span style="color: #800080;"&gt;21&lt;/span&gt;,&lt;span style="color: #800080;"&gt;22&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800080;"&gt;23&lt;/span&gt;,&lt;span style="color: #800080;"&gt;24&lt;/span&gt;,&lt;span style="color: #800080;"&gt;25&lt;/span&gt;,&lt;span style="color: #800080;"&gt;26&lt;/span&gt;,&lt;span style="color: #800080;"&gt;27&lt;/span&gt;,&lt;span style="color: #800080;"&gt;28&lt;/span&gt;,&lt;span style="color: #800080;"&gt;29&lt;/span&gt;|...]&lt;br /&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&amp;gt; rp(L).&lt;br /&gt;[&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;,&lt;span style="color: #800080;"&gt;3&lt;/span&gt;,&lt;span style="color: #800080;"&gt;4&lt;/span&gt;,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;,&lt;span style="color: #800080;"&gt;6&lt;/span&gt;,&lt;span style="color: #800080;"&gt;7&lt;/span&gt;,&lt;span style="color: #800080;"&gt;8&lt;/span&gt;,&lt;span style="color: #800080;"&gt;9&lt;/span&gt;,&lt;span style="color: #800080;"&gt;10&lt;/span&gt;,&lt;span style="color: #800080;"&gt;11&lt;/span&gt;,&lt;span style="color: #800080;"&gt;12&lt;/span&gt;,&lt;span style="color: #800080;"&gt;13&lt;/span&gt;,&lt;span style="color: #800080;"&gt;14&lt;/span&gt;,&lt;span style="color: #800080;"&gt;15&lt;/span&gt;,&lt;span style="color: #800080;"&gt;16&lt;/span&gt;,&lt;span style="color: #800080;"&gt;17&lt;/span&gt;,&lt;span style="color: #800080;"&gt;18&lt;/span&gt;,&lt;span style="color: #800080;"&gt;19&lt;/span&gt;,&lt;span style="color: #800080;"&gt;20&lt;/span&gt;,&lt;span style="color: #800080;"&gt;21&lt;/span&gt;,&lt;span style="color: #800080;"&gt;22&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800080;"&gt;23&lt;/span&gt;,&lt;span style="color: #800080;"&gt;24&lt;/span&gt;,&lt;span style="color: #800080;"&gt;25&lt;/span&gt;,&lt;span style="color: #800080;"&gt;26&lt;/span&gt;,&lt;span style="color: #800080;"&gt;27&lt;/span&gt;,&lt;span style="color: #800080;"&gt;28&lt;/span&gt;,&lt;span style="color: #800080;"&gt;29&lt;/span&gt;,&lt;span style="color: #800080;"&gt;30&lt;/span&gt;,&lt;span style="color: #800080;"&gt;31&lt;/span&gt;,&lt;span style="color: #800080;"&gt;32&lt;/span&gt;,&lt;span style="color: #800080;"&gt;33&lt;/span&gt;,&lt;span style="color: #800080;"&gt;34&lt;/span&gt;,&lt;span style="color: #800080;"&gt;35&lt;/span&gt;,&lt;span style="color: #800080;"&gt;36&lt;/span&gt;,&lt;span style="color: #800080;"&gt;37&lt;/span&gt;,&lt;span style="color: #800080;"&gt;38&lt;/span&gt;,&lt;span style="color: #800080;"&gt;39&lt;/span&gt;,&lt;span style="color: #800080;"&gt;40&lt;/span&gt;,&lt;span style="color: #800080;"&gt;41&lt;/span&gt;,&lt;span style="color: #800080;"&gt;42&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800080;"&gt;43&lt;/span&gt;,&lt;span style="color: #800080;"&gt;44&lt;/span&gt;,&lt;span style="color: #800080;"&gt;45&lt;/span&gt;,&lt;span style="color: #800080;"&gt;46&lt;/span&gt;,&lt;span style="color: #800080;"&gt;47&lt;/span&gt;,&lt;span style="color: #800080;"&gt;48&lt;/span&gt;,&lt;span style="color: #800080;"&gt;49&lt;/span&gt;,&lt;span style="color: #800080;"&gt;50&lt;/span&gt;,&lt;span style="color: #800080;"&gt;51&lt;/span&gt;,&lt;span style="color: #800080;"&gt;52&lt;/span&gt;,&lt;span style="color: #800080;"&gt;53&lt;/span&gt;,&lt;span style="color: #800080;"&gt;54&lt;/span&gt;,&lt;span style="color: #800080;"&gt;55&lt;/span&gt;,&lt;span style="color: #800080;"&gt;56&lt;/span&gt;,&lt;span style="color: #800080;"&gt;57&lt;/span&gt;,&lt;span style="color: #800080;"&gt;58&lt;/span&gt;,&lt;span style="color: #800080;"&gt;59&lt;/span&gt;,&lt;span style="color: #800080;"&gt;60&lt;/span&gt;,&lt;span style="color: #800080;"&gt;61&lt;/span&gt;,&lt;span style="color: #800080;"&gt;62&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800080;"&gt;63&lt;/span&gt;,&lt;span style="color: #800080;"&gt;64&lt;/span&gt;,&lt;span style="color: #800080;"&gt;65&lt;/span&gt;,&lt;span style="color: #800080;"&gt;66&lt;/span&gt;,&lt;span style="color: #800080;"&gt;67&lt;/span&gt;,&lt;span style="color: #800080;"&gt;68&lt;/span&gt;,&lt;span style="color: #800080;"&gt;69&lt;/span&gt;,&lt;span style="color: #800080;"&gt;70&lt;/span&gt;,&lt;span style="color: #800080;"&gt;71&lt;/span&gt;,&lt;span style="color: #800080;"&gt;72&lt;/span&gt;,&lt;span style="color: #800080;"&gt;73&lt;/span&gt;,&lt;span style="color: #800080;"&gt;74&lt;/span&gt;,&lt;span style="color: #800080;"&gt;75&lt;/span&gt;,&lt;span style="color: #800080;"&gt;76&lt;/span&gt;,&lt;span style="color: #800080;"&gt;77&lt;/span&gt;,&lt;span style="color: #800080;"&gt;78&lt;/span&gt;,&lt;span style="color: #800080;"&gt;79&lt;/span&gt;,&lt;span style="color: #800080;"&gt;80&lt;/span&gt;,&lt;span style="color: #800080;"&gt;81&lt;/span&gt;,&lt;span style="color: #800080;"&gt;82&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800080;"&gt;83&lt;/span&gt;,&lt;span style="color: #800080;"&gt;84&lt;/span&gt;,&lt;span style="color: #800080;"&gt;85&lt;/span&gt;,&lt;span style="color: #800080;"&gt;86&lt;/span&gt;,&lt;span style="color: #800080;"&gt;87&lt;/span&gt;,&lt;span style="color: #800080;"&gt;88&lt;/span&gt;,&lt;span style="color: #800080;"&gt;89&lt;/span&gt;,&lt;span style="color: #800080;"&gt;90&lt;/span&gt;,&lt;span style="color: #800080;"&gt;91&lt;/span&gt;,&lt;span style="color: #800080;"&gt;92&lt;/span&gt;,&lt;span style="color: #800080;"&gt;93&lt;/span&gt;,&lt;span style="color: #800080;"&gt;94&lt;/span&gt;,&lt;span style="color: #800080;"&gt;95&lt;/span&gt;,&lt;span style="color: #800080;"&gt;96&lt;/span&gt;,&lt;span style="color: #800080;"&gt;97&lt;/span&gt;,&lt;span style="color: #800080;"&gt;98&lt;/span&gt;,&lt;span style="color: #800080;"&gt;99&lt;/span&gt;,&lt;span style="color: #800080;"&gt;100&lt;/span&gt;]&lt;br /&gt;ok&lt;br /&gt;&lt;span style="color: #800080;"&gt;11&lt;/span&gt;&amp;gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;有必要了解一下shell中提供的方法:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;Eshell V5.&lt;span style="color: #800080;"&gt;9&lt;/span&gt;  (abort with ^G)&lt;br /&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;gt; help().&lt;br /&gt;** shell internal commands **&lt;br /&gt;b()        -- display all variable bindings&lt;br /&gt;e(N)       -- repeat the expression &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; query &amp;lt;N&amp;gt;&lt;br /&gt;f()        -- forget all variable bindings&lt;br /&gt;f(X)       -- forget the binding of variable X&lt;br /&gt;h()        -- history&lt;br /&gt;history(N) -- set how many previous commands to keep&lt;br /&gt;results(N) -- set how many previous command results to keep&lt;br /&gt;catch_exception(B) -- how exceptions are handled&lt;br /&gt;v(N)       -- use the value of query &amp;lt;N&amp;gt;&lt;br /&gt;rd(R,D)    -- define a record&lt;br /&gt;rf()       -- remove all record information&lt;br /&gt;rf(R)      -- remove record information about R&lt;br /&gt;rl()       -- display all record information&lt;br /&gt;rl(R)      -- display record information about R&lt;br /&gt;rp(Term)   -- display Term using the shell&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;s record information&lt;br /&gt;rr(File)   -- read record information from File (wildcards allowed)&lt;br /&gt;rr(F,R)    -- read selected record information from file(s)&lt;br /&gt;rr(F,R,O)  -- read selected record information with options&lt;br /&gt;** commands in module c **&lt;br /&gt;bt(Pid)    -- stack backtrace for a process&lt;br /&gt;c(File)    -- compile and load code in &amp;lt;File&amp;gt;&lt;br /&gt;cd(Dir)    -- change working directory&lt;br /&gt;flush()    -- flush any messages sent to the shell&lt;br /&gt;help()     -- help info&lt;br /&gt;i()        -- information about the system&lt;br /&gt;ni()       -- information about the networked system&lt;br /&gt;i(X,Y,Z)   -- information about pid &amp;lt;X,Y,Z&amp;gt;&lt;br /&gt;l(Module)  -- load or reload module&lt;br /&gt;lc([File]) -- compile a list of Erlang modules&lt;br /&gt;ls()       -- list files in the current directory&lt;br /&gt;ls(Dir)    -- list files in directory &amp;lt;Dir&amp;gt;&lt;br /&gt;m()        -- which modules are loaded&lt;br /&gt;m(Mod)     -- information about module &amp;lt;Mod&amp;gt;&lt;br /&gt;memory()   -- memory allocation information&lt;br /&gt;memory(T)  -- memory allocation information of type &amp;lt;T&amp;gt;&lt;br /&gt;nc(File)   -- compile and load code in &amp;lt;File&amp;gt; on all nodes&lt;br /&gt;nl(Module) -- load module on all nodes&lt;br /&gt;pid(X,Y,Z) -- convert X,Y,Z to a Pid&lt;br /&gt;pwd()      -- print working directory&lt;br /&gt;q()        -- quit - shorthand for init:stop()&lt;br /&gt;regs()     -- information about registered processes&lt;br /&gt;nregs()    -- information about all registered processes&lt;br /&gt;xm(M)      -- cross reference check a module&lt;br /&gt;y(File)    -- generate a Yecc parser&lt;br /&gt;** commands in module i (interpreter interface) **&lt;br /&gt;ih()       -- print help for the i module&lt;br /&gt;true&lt;br /&gt;2&amp;gt;&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;span&gt;这些方法的内部实现为:&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;bi(I)           -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;bi(I).&lt;br /&gt;&lt;span style="color: #0000ff;"&gt;bt&lt;/span&gt;(Pid)          -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;bt&lt;/span&gt;(Pid).&lt;br /&gt;c(File)      -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;c(File).&lt;br /&gt;c(File, Opt)    -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;c(File, Opt).&lt;br /&gt;cd(D)           -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;cd(D).&lt;br /&gt;erlangrc(X)      -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;erlangrc(X).&lt;br /&gt;flush()         -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;flush().&lt;br /&gt;i()           -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;i().&lt;br /&gt;i(X,Y,Z)      -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;i(X,Y,Z).&lt;br /&gt;l(Mod)            -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;l(Mod).&lt;br /&gt;lc(X)            -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;lc(X).&lt;br /&gt;ls()            -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;ls().&lt;br /&gt;ls(S)           -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;ls(S).&lt;br /&gt;m()           -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;m().&lt;br /&gt;m(Mod)           -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;m(Mod).&lt;br /&gt;memory()        -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;memory().&lt;br /&gt;memory(Type)    -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;memory(Type).&lt;br /&gt;nc(X)          -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;nc(X).&lt;br /&gt;ni()            -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;ni().&lt;br /&gt;nl(Mod)      -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;nl(Mod).&lt;br /&gt;nregs()         -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;nregs().&lt;br /&gt;pid(X,Y,Z)      -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;pid(X,Y,Z).&lt;br /&gt;pwd()           -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;pwd().&lt;br /&gt;q()          -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;q().&lt;br /&gt;regs()          -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;regs().&lt;br /&gt;xm(Mod)         -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;xm(Mod).&lt;br /&gt;y(File)         -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;y(File).&lt;br /&gt;y(File, Opts)   -&amp;gt; &lt;span style="color: #008080;"&gt;c:&lt;/span&gt;y(File, Opts).&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;代码参见:&lt;a href="http://www.google.com/codesearch#dNzC48WMK6w/lib/stdlib/src/shell_default.erl&amp;amp;ct=rc&amp;amp;cd=1&amp;amp;q=shell_default%20lang:erlang"&gt;http://www.google.com/codesearch#dNzC48WMK6w/lib/stdlib/src/shell_default.erl&amp;amp;ct=rc&amp;amp;cd=1&amp;amp;q=shell_default%20lang:erlang&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;晚安!&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/me-sa/aggbug/2318583.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2012/01/10/erlang0031.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/me-sa/archive/2012/01/10/erlang0030.html</id><title type="text">[Erlang 0030] 理解Erlang/OTP Supervisor</title><summary type="text">Supervisor的基本思想就是通过建立层级结构实现错误隔离和管理,具体方法是通过重启的方式保持子进程一直活着.</summary><published>2012-01-10T06:17:00Z</published><updated>2012-01-10T06:17:00Z</updated><author><name>坚强2002</name><uri>http://www.cnblogs.com/me-sa/</uri></author><link rel="alternate" href="http://www.cnblogs.com/me-sa/archive/2012/01/10/erlang0030.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/me-sa/archive/2012/01/10/erlang0030.html"/><content type="html">&lt;p&gt;Supervisors are used to build an hierarchical process structure called a supervision tree, a nice way to structure a fault tolerant application.&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;--Erlang/OTP Doc&lt;/p&gt;&#xD;
&lt;p&gt;Supervisor的基本思想就是通过建立层级结构实现错误隔离和管理,具体方法是通过重启的方式保持子进程一直活着.如果supervisor是进程树的一部分,它会被它的supervisor自动终止,当它的supervisor让它shutdown的时候,它会按照子进程启动顺序的逆序终止其所有的子进程,最后终止掉自己.&lt;a href="http://www.cnblogs.com/me-sa/archive/2011/12/27/erlang0025.html"&gt;[Erlang 0025]理解Erlang/OTP - Application&lt;/a&gt;以log4erl项目为学习了Erlang/OTP application,我们说到application在start的方法中启动了log4erl的顶层监控树.今天我们继续跟进,看log4erl的监控树是怎么构建起来的,并做实验看supervisor如何通过重启恢复服务的.使用application:start(log4erl).启动起来之后的进程树:&lt;/p&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/17329/2012011014085695.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span&gt;下面是log4erl_sup文件的start_link方法,supervisor:start_link方法的执行是同步的,直到所有的子进程都启动了才会返回.&lt;span&gt;&amp;nbsp;&lt;/span&gt;supervisor:start_link会使用回调函数init/1.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;start_link(Default_logger) -&amp;gt;&lt;br /&gt;    R = &lt;span style="color: #008080;"&gt;supervisor:&lt;/span&gt;start_link({local, ?MODULE}, ?MODULE, []),&lt;br /&gt;    %&lt;span style="color: #008080;"&gt;log4erl:&lt;/span&gt;start_link(Default_logger),&lt;br /&gt;    add_logger(Default_logger),&lt;br /&gt;    ?LOG2(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Result in supervisor is ~p~n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,[R]),&lt;br /&gt;    R.&lt;br /&gt;&lt;br /&gt;%%回调的方法init/&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;br /&gt;init([]) -&amp;gt;&lt;br /&gt;    {ok,&lt;br /&gt;     {&lt;br /&gt;       {one_for_one,&lt;span style="color: #800080;"&gt;3&lt;/span&gt;,&lt;span style="color: #800080;"&gt;10&lt;/span&gt;}, &lt;br /&gt;       []&lt;br /&gt;      }&lt;br /&gt;    }.&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp; log4erl的顶层监控树的初始化相当简单仅仅定义了重启策略(RestartStrategy)和最大重启频率(maximum restart frequency):{one_for_one,3,10}.&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&amp;nbsp;{one_for_one,3,10}&lt;/span&gt;表达的语义是&lt;/span&gt;{How, Max, Within}&lt;span&gt;:&lt;/span&gt;在多长时间内(Within)重启了几次(Max),如何重启(HOW 重启策略);&lt;span&gt;&lt;span&gt;设计最大重启频率是为了避免反复重启进入死循环,一旦超出了此阈值,&lt;/span&gt;&lt;/span&gt;supervisor进程会结束掉自己以及它所有的子进程,并通过进程树传递退出消息,更上层的supervisor就会采取适当的措施,要么重启终止的supervisor要么自己也终止掉.可能比较纠结这几个值怎么配置,多数资料上都会告诉你"如何配置完全取决于你的应用程序".这个还是有经验值的,生成环境的经验值是一小时内重启4次,也可以参考一些和你应用类似的开源项目看看它们是怎么配置的.如果填写的是{one_for_one,0,1}就是不允许重启,下面的示例中可以看到YAWS项目采用了这样的策略.&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;下面几个开源项目顶层supervisor的init方法:&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;%%rabbit_sup.erl  来自大名鼎鼎的rabbitmq&lt;br /&gt;init([]) -&amp;gt;&lt;br /&gt;    {ok, {{one_for_all, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;1&lt;/span&gt;}, []}}.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;%%yaws_sup.erl  Yaws项目 - Yet Another Web Server&lt;br /&gt;init([]) -&amp;gt;&lt;br /&gt;&lt;br /&gt;    ChildSpecs = child_specs(),&lt;br /&gt;    %% &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;1&lt;/span&gt; means that we never want supervisor restarts&lt;br /&gt;    {ok,{{one_for_all, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;1&lt;/span&gt;}, ChildSpecs}}.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;%%ejabberd_sup ejabberd项目&lt;br /&gt;init([]) -&amp;gt;&lt;br /&gt;    Hooks =&lt;br /&gt;     {ejabberd_hooks,&lt;br /&gt;     {ejabberd_hooks, start_link, []},&lt;br /&gt;   %%......................... 省略代码&lt;br /&gt;    {ok, {{one_for_one, &lt;span style="color: #800080;"&gt;10&lt;/span&gt;, &lt;span style="color: #800080;"&gt;1&lt;/span&gt;},&lt;br /&gt;       [Hooks,&lt;br /&gt;           GlobalRouter,&lt;br /&gt;        Cluster,&lt;br /&gt;      ..................&lt;br /&gt;        Listener]}}.&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;strong&gt;&lt;br /&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;strong&gt;重启策略&lt;/strong&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&amp;nbsp;one-for-one : 把子进程当成各自独立的,一个进程出现问题其它进程不会受到崩溃的进程的影响.该&lt;span&gt;子进程死掉,只有这个进程会被重启&lt;/span&gt;&lt;br /&gt;&#xD;
&amp;nbsp;one_for_all : 如果子进程终止,所有其它子进程也都会被终止,然后所有进程都会被重启.&lt;br /&gt;&#xD;
&amp;nbsp;rest_for_one:如果一个子进程终止,在这个进程启动之后启动的进程都会被终止掉.然后终止掉的进程和连带关闭的进程都会被重启.&lt;br /&gt;&#xD;
&amp;nbsp;simple_one_for_one 是one_for_one的简化版 ,所有子进程都动态添加同一种进程的实例&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;br /&gt;&#xD;
在log4erl_sup.erl的start_link中启动了顶层supervisor之后,添加了一个默认的logger:&lt;/span&gt;&amp;nbsp;add_logger(Default_logger),&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;add_logger(Name) when is_atom(Name) -&amp;gt;&lt;br /&gt;    N = atom_to_list(Name),&lt;br /&gt;    add_logger(N)&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;add_logger(Name) when is_list(Name) -&amp;gt;&lt;br /&gt;    C1 = {Name,&lt;br /&gt;       {log_manager, start_link ,[Name]},&lt;br /&gt;       permanent,&lt;br /&gt;       &lt;span style="color: #800080;"&gt;10000&lt;/span&gt;,&lt;br /&gt;       worker,&lt;br /&gt;       [log_manager]},&lt;br /&gt;   &lt;br /&gt;    ?LOG2(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Adding ~p to ~p~n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,[C1, ?MODULE]),&lt;br /&gt;    &lt;span style="color: #008080;"&gt;supervisor:&lt;/span&gt;start_child(?MODULE, C1).&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;添加的logger是log4erl_sup的子进程,子进程启动和监控的方式通过child specification来指定.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&amp;nbsp;C1 =&lt;span&gt;&amp;nbsp;&lt;/span&gt;&amp;nbsp;&lt;/span&gt;{Name,{log_manager, start_link ,[Name]},permanent,10000,worker,[log_manager]}&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;C1的六个数据项分别为: {ID, StartEntery, Restart, Shutdown, Type, Modules}:&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;ID&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;:supervisor 用来在内部区分specification的,所以只要子进程规格说明之间不重复就可以.&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;Start&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 启动参数{M,F,A}&lt;br /&gt;&lt;strong&gt;Restart&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;: 这个进程遇到错误之后是否重启&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; permanent:遇到任何错误导致进程终止就会重启&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; temporary:进程永远都不会被重启&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; transient: 只有进程异常终止的时候会被重启&lt;br /&gt;&lt;strong&gt;Shutdown&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;进程如何被干掉,这里是使用整型值2000的意思是,进程在被强制干掉之前有2000毫秒的时间料理后事自行终止.&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 实际过程是supervisor给子进程发送一个exit(Pid,shutdown)然后等待exit信号返回,在指定时间没有返回则将子进程使用exit(Child,kill)&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;这里的参数还有 brutal_kill 意思是进程马上就会被干掉&lt;br /&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;infinity :当一个子进程是supervisor那么就要用infinity,意思是给supervisor足够的时间进行重启.&lt;br /&gt;&lt;strong&gt;Type&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;这里只有两个值:supervisor worker ; 只要没有实现supervisor behavior的进程都是worker;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 可以通过supervisor的层级结构来精细化对进程的控制.这个值主要作用是告知监控进程它的子进程是supervisor还是worker&lt;br /&gt;&lt;strong&gt;Modules&lt;/strong&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;是进程依赖的模块,&lt;span style="color: #ff0000;"&gt;这个信息只有在代码热更新的时候才会被用到&lt;/span&gt;:标注了哪些模块需要按照什么顺序进行更新;通常这里只需要列出进程依赖的主模块.&amp;nbsp;如果子进程是supervisor gen_server gen_fsm Module名是回调模块的名称,这时Modules的值是只有一个元素的列表,元素就是回调模块的名称;如果子进程是gen_event Modules的值是 dynamic;关于dynamic参数余锋有一篇专门的分析:Erlang supervisor规格的dynamic行为分析&amp;nbsp;&lt;a href="http://blog.yufeng.info/archives/1455"&gt;http://blog.yufeng.info/archives/1455&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;实际应用中log4erl中的logger会根据业务逻辑添加多个,我们也不是直接通过application:start(log4erl).而是调用&amp;nbsp; log4erl:conf(log4erl.conf)这个方法简单的封装了内部逻辑,实际调用的是&lt;/span&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;log4erl_conf:conf(File).我们这里定义一个简单的log4erl.conf文件,使用log4erl:conf(log4erl.conf).启动之后,我们看看它的进程树是什么样的:&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;div&gt;&lt;span&gt;%%log4erl.conf文件 内容我做了简单的缩排&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;%%mod&lt;br /&gt;&#xD;
logger default_logger{&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; file_appender default_app{&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp; dir = "./log", level = debug, file = default_log, type = size, max = 1000000, suffix = log, rotation = 50, format = ' %d %h:%m:%s.%i %l%n'&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&#xD;
}&lt;br /&gt;&lt;br /&gt;&#xD;
%%mail mod&lt;br /&gt;&#xD;
logger mail_logger{&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; file_appender mail_app{&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dir = "./log", level = debug, file = mail_log, type = size, max = 1000000, suffix = log, rotation = 50, format = ' %d %h:%m:%s.%i %l%n'&lt;br /&gt;&#xD;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;&#xD;
}&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;对应的进程树是这样的,进程之间的红线表示link关系:&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/17329/2012011014120616.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;我们沿着调用关系,逐步跟进代码:&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;%==== File : log4erl_conf =======&lt;br /&gt;&lt;br /&gt;%%&lt;span style="color: #008080;"&gt;log4erl_conf:&lt;/span&gt;conf(File).&lt;br /&gt;conf(File) -&amp;gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;application:&lt;/span&gt;start(log4erl),     %%启动log4erl&lt;br /&gt;    Tree = parse(leex(File)),     %%解析配置文件&lt;br /&gt;    traverse(Tree).                   %%遍历配置项构造监控树&lt;br /&gt;&lt;br /&gt;%%跟进遍历的逻辑,对于每一条配置执行的是element/1方法&lt;br /&gt;traverse([]) -&amp;gt;&lt;br /&gt;    ok&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;traverse([H|Tree]) -&amp;gt;&lt;br /&gt;    element(H),&lt;br /&gt;    traverse(Tree).&lt;br /&gt;&lt;br /&gt;%%对于我们自定义的logger走的是{logger, Logger, Appenders}逻辑&lt;br /&gt;element({cutoff_level, CutoffLevel}) -&amp;gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;log_filter_codegen:&lt;/span&gt;set_cutoff_level(CutoffLevel)&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;element({default_logger, Appenders}) -&amp;gt;&lt;br /&gt;    appenders(Appenders)&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;element({logger, Logger, Appenders}) -&amp;gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;log4erl:&lt;/span&gt;add_logger(Logger),                &lt;br /&gt;    appenders(Logger, Appenders). &lt;br /&gt;&lt;br /&gt;%==== File : log4erl  =======&lt;br /&gt;%%&lt;span style="color: #008080;"&gt;继续跟进我们走到log4erl:&lt;/span&gt;add_logger/&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;br /&gt;add_logger(Logger) -&amp;gt;&lt;br /&gt;    try_msg({add_logger, Logger}).&lt;br /&gt;&lt;br /&gt;%%try_msg 是的添加了异常捕获的通用方法&lt;br /&gt;try_msg(Msg) -&amp;gt;&lt;br /&gt;     try&lt;br /&gt;     handle_call(Msg)&lt;br /&gt;     catch&lt;br /&gt;     &lt;span style="color: #008080;"&gt;exit:&lt;/span&gt;{noproc, _M} -&amp;gt;&lt;br /&gt;          &lt;span style="color: #008080;"&gt;io:&lt;/span&gt;format(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;log4erl has not been initialized yet. To do so, please run~n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;),&lt;br /&gt;          &lt;span style="color: #008080;"&gt;io:&lt;/span&gt;format(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;&amp;gt; application:start(log4erl).~n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;),&lt;br /&gt;          {error, log4erl_not_started}&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;        &lt;span style="color: #008080;"&gt;E:&lt;/span&gt;M -&amp;gt;&lt;br /&gt;          ?LOG2(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Error message received by log4erl is ~p:~p~n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,[E, M]),&lt;br /&gt;          {E, M}&lt;br /&gt;     end.&lt;br /&gt;&lt;br /&gt;%%handle_call的代码片段&lt;br /&gt;handle_call({add_logger, Logger}) -&amp;gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;log_manager:&lt;/span&gt;add_logger(Logger)&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;%==== File :  log_manager  =======&lt;br /&gt;%%逻辑转到log_manager的add_logger(Logger)&lt;br /&gt;%%&lt;span style="color: #008080;"&gt;最终调用的是log4erl_sup:&lt;/span&gt;add_logger(Logger).这个我们上面已经分析过了&lt;br /&gt;add_logger(Logger) -&amp;gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;log4erl_sup:&lt;/span&gt;add_logger(Logger).&lt;br /&gt;&lt;br /&gt;%%element方法在添加loger之后会添加appender&lt;br /&gt;appenders([]) -&amp;gt;&lt;br /&gt;    ok&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;appenders([H|Apps]) -&amp;gt;&lt;br /&gt;    appender(H),&lt;br /&gt;    appenders(Apps).&lt;br /&gt;&lt;br /&gt;appenders(_, []) -&amp;gt;&lt;br /&gt;    ok&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;appenders(Logger, [H|Apps]) -&amp;gt;&lt;br /&gt;    appender(Logger, H),&lt;br /&gt;    appenders(Logger, Apps).&lt;br /&gt;&lt;br /&gt;appender({appender, App, Name, Conf}) -&amp;gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;log4erl:&lt;/span&gt;add_appender({App, Name}, {conf, Conf}).&lt;br /&gt;&lt;br /&gt;appender(Logger, {appender, App, Name, Conf}) -&amp;gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;log4erl:&lt;/span&gt;add_appender(Logger, {App, Name}, {conf, Conf}).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;%==== File :  log4erl  =======&lt;br /&gt;%% Appender = {Appender, Name}&lt;br /&gt;add_appender(Logger, Appender, Conf) -&amp;gt;&lt;br /&gt;    try_msg({add_appender, Logger, Appender, Conf}).&lt;br /&gt;&lt;br /&gt;handle_call({add_appender, Logger, Appender, Conf}) -&amp;gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;log_manager:&lt;/span&gt;add_appender(Logger, Appender, Conf)&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;%==== File :  log_manager =======&lt;br /&gt;add_appender(Logger, {Appender, Name} , Conf) -&amp;gt;&lt;br /&gt;    ?LOG2(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;add_appender ~p with name ~p to ~p with Conf ~p ~n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,[Appender, Name, Logger, Conf]),&lt;br /&gt;    &lt;span style="color: #008080;"&gt;log4erl_sup:&lt;/span&gt;add_guard(Logger, Appender, Name, Conf).&lt;br /&gt;&lt;br /&gt;%==== File :  log4erl_sup =======&lt;br /&gt;add_guard(Logger, Appender, Name, Conf) -&amp;gt;&lt;br /&gt;    C = {Name,&lt;br /&gt;     {logger_guard, start_link ,[Logger, Appender, Name, Conf]},&lt;br /&gt;     permanent,&lt;br /&gt;     &lt;span style="color: #800080;"&gt;10000&lt;/span&gt;,&lt;br /&gt;     worker,&lt;br /&gt;     [logger_guard]},&lt;br /&gt;    ?LOG2(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Adding ~p to ~p~n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,[C, ?MODULE]),&lt;br /&gt;    &lt;span style="color: #008080;"&gt;supervisor:&lt;/span&gt;start_child(?MODULE, C).&lt;br /&gt;&lt;br /&gt;%==== File :  logger_guard =======&lt;br /&gt;start_link(Logger, Appender, Name, Conf) -&amp;gt;&lt;br /&gt;    %?LOG2(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;starting guard for logger ~p~n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,[Logger]),&lt;br /&gt;    {ok, Pid} = &lt;span style="color: #008080;"&gt;gen_server:&lt;/span&gt;start_link(?MODULE, [Appender, Name], []),&lt;br /&gt;    case add_sup_handler(Pid, Logger, Conf) of&lt;br /&gt;     {error, E} -&amp;gt;&lt;br /&gt;         &lt;span style="color: #008080;"&gt;gen_server:&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;call&lt;/span&gt;(Pid, stop),&lt;br /&gt;         {error, E}&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;     _R -&amp;gt;&lt;br /&gt;         {ok, Pid}&lt;br /&gt;    end.&lt;br /&gt;&lt;br /&gt;add_sup_handler(G_pid, Logger, Conf) -&amp;gt;&lt;br /&gt;    ?LOG(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;add_sup()~n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;),&lt;br /&gt;    &lt;span style="color: #008080;"&gt;gen_server:&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;call&lt;/span&gt;(G_pid, {add_sup_handler, Logger, Conf}).&lt;br /&gt;&lt;br /&gt;handle_call({add_sup_handler, Logger, Conf}, _From, [{appender, Appender, Name}] = State) -&amp;gt;&lt;br /&gt;    ?LOG2(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;Adding handler ~p with name ~p for ~p From ~p~n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,[Appender, Name, Logger, _From]),&lt;br /&gt;    try&lt;br /&gt;     Res = &lt;span style="color: #008080;"&gt;gen_event:&lt;/span&gt;add_sup_handler(Logger, {Appender, Name}, Conf),&lt;br /&gt;     {reply, Res, State}&lt;br /&gt;    catch&lt;br /&gt;     &lt;span style="color: #008080;"&gt;E:&lt;/span&gt;R -&amp;gt;&lt;br /&gt;         {reply, {error, {E,R}}, State}&lt;br /&gt;    end&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;gen_event:add_sup_handler会建立EventManager与Event Handler之间的link的关系,所以我们修改一下,注释掉这段,看看监控树是什么样子:&lt;/p&gt;&#xD;
&lt;div&gt;add_sup_handler(G_pid, Logger, Conf) -&amp;gt;&lt;/div&gt;&#xD;
&lt;p&gt;%&amp;nbsp;&amp;nbsp;&amp;nbsp; ?LOG("add_sup()~n"),&lt;br /&gt; %&amp;nbsp;&amp;nbsp;&amp;nbsp; gen_server:call(G_pid, {add_sup_handler, Logger, Conf}).&lt;br /&gt;&amp;nbsp; ok.&lt;/p&gt;&#xD;
&lt;div&gt;注释掉之后可以看到logger和guard之间的link关系就不存在了.&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/17329/2012011014140661.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;kill进程的实验&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;后面我们会用各种情况杀掉进程,看这个进程树对异常的处理情况;我们的实验步骤:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;1.发送退出消息Reason:some_reason给default_logger&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;2.&lt;/span&gt;发送退出消息Reason:kill 给default_logger&lt;/div&gt;&#xD;
&lt;div&gt;3.发送退出消息Reason:some_reason给logger_guard&lt;/div&gt;&#xD;
&lt;div&gt;4.发送退出消息Reason:some_reason给log4erl_sup&lt;/div&gt;&#xD;
&lt;div&gt;5.发送退出消息Reason:kill 给log4erl_sup&lt;/div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&amp;gt; whereis(default_logger).&lt;br /&gt;&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;45&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&amp;gt; exit(whereis(default_logger),some_reason).&lt;br /&gt;true&lt;br /&gt;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;&amp;gt; whereis(default_logger).&lt;br /&gt;&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;45&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;6&lt;/span&gt;&amp;gt; exit(whereis(default_logger),some_reason). %%由于gen_event默认process_flag(trap_exit, true),所以some_reason的退出消息并没有把它干掉&lt;br /&gt;true&lt;br /&gt;&lt;span style="color: #800080;"&gt;7&lt;/span&gt;&amp;gt; whereis(default_logger).&lt;br /&gt;&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;45&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;8&lt;/span&gt;&amp;gt; exit(whereis(default_logger),kill).    %%向进程发送强制退出消息,&lt;br /&gt;true&lt;br /&gt;&lt;br /&gt;=SUPERVISOR REPORT==== &lt;span style="color: #800080;"&gt;10&lt;/span&gt;-Jan-&lt;span style="color: #800080;"&gt;2012&lt;/span&gt;::&lt;span style="color: #800080;"&gt;10&lt;/span&gt;:&lt;span style="color: #800080;"&gt;35&lt;/span&gt;:&lt;span style="color: #800080;"&gt;21&lt;/span&gt; ===      %首先能够看到log4erl报出的子进程终止的报告&lt;br /&gt;     &lt;span style="color: #008080;"&gt;Supervisor:&lt;/span&gt; {local,log4erl_sup}&lt;br /&gt;     &lt;span style="color: #008080;"&gt;Context:&lt;/span&gt;    child_terminated&lt;br /&gt;     &lt;span style="color: #008080;"&gt;Reason:&lt;/span&gt;     killed&lt;br /&gt;     &lt;span style="color: #008080;"&gt;Offender:&lt;/span&gt;   [{pid,&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;45&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;},&lt;br /&gt;                  {name,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;default_logger&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;},&lt;br /&gt;                  {mfargs,{log_manager,start_link,[&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;default_logger&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;]}},&lt;br /&gt;                  {restart_type,permanent},&lt;br /&gt;                  {shutdown,&lt;span style="color: #800080;"&gt;10000&lt;/span&gt;},&lt;br /&gt;                  {child_type,worker}]&lt;br /&gt;&lt;br /&gt;=PROGRESS REPORT==== &lt;span style="color: #800080;"&gt;10&lt;/span&gt;-Jan-&lt;span style="color: #800080;"&gt;2012&lt;/span&gt;::&lt;span style="color: #800080;"&gt;10&lt;/span&gt;:&lt;span style="color: #800080;"&gt;35&lt;/span&gt;:&lt;span style="color: #800080;"&gt;21&lt;/span&gt; ===      %log4erl_sup重建default_logger,新进程pid是&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;69&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;&lt;br /&gt;          &lt;span style="color: #008080;"&gt;supervisor:&lt;/span&gt; {local,log4erl_sup}&lt;br /&gt;             &lt;span style="color: #008080;"&gt;started:&lt;/span&gt; [{pid,&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;69&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;},&lt;br /&gt;                       {name,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;default_logger&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;},&lt;br /&gt;                       {mfargs,{log_manager,start_link,[&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;default_logger&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;]}},&lt;br /&gt;                       {restart_type,permanent},&lt;br /&gt;                       {shutdown,&lt;span style="color: #800080;"&gt;10000&lt;/span&gt;},&lt;br /&gt;                       {child_type,worker}]&lt;br /&gt;&lt;br /&gt;=SUPERVISOR REPORT==== &lt;span style="color: #800080;"&gt;10&lt;/span&gt;-Jan-&lt;span style="color: #800080;"&gt;2012&lt;/span&gt;::&lt;span style="color: #800080;"&gt;10&lt;/span&gt;:&lt;span style="color: #800080;"&gt;35&lt;/span&gt;:&lt;span style="color: #800080;"&gt;21&lt;/span&gt; ===  %default_logger退出消息转变成为killed继续广播给link的进程,对应的logger_guard终止&lt;br /&gt;     &lt;span style="color: #008080;"&gt;Supervisor:&lt;/span&gt; {local,log4erl_sup}&lt;br /&gt;     &lt;span style="color: #008080;"&gt;Context:&lt;/span&gt;    child_terminated&lt;br /&gt;     &lt;span style="color: #008080;"&gt;Reason:&lt;/span&gt;     killed&lt;br /&gt;     &lt;span style="color: #008080;"&gt;Offender:&lt;/span&gt;   [{pid,&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;46&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;},&lt;br /&gt;                  {name,default_app},&lt;br /&gt;                  {mfargs,&lt;br /&gt;                      {logger_guard,start_link,&lt;br /&gt;                          [default_logger,file_appender,default_app,&lt;br /&gt;                           {conf, [{dir,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;./log&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;},{level,debug},{file,default_log},{type,size},&lt;br /&gt;                                {max,&lt;span style="color: #800080;"&gt;1000000&lt;/span&gt;},{suffix,log}, {rotation,&lt;span style="color: #800080;"&gt;50&lt;/span&gt;},&lt;br /&gt;                                {format,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt; %d %h:%m:%s.%i %l%n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;}]}]}},&lt;br /&gt;                  {restart_type,permanent},&lt;br /&gt;                  {shutdown,&lt;span style="color: #800080;"&gt;10000&lt;/span&gt;},&lt;br /&gt;                  {child_type,worker}]&lt;br /&gt;&lt;br /&gt;=PROGRESS REPORT==== &lt;span style="color: #800080;"&gt;10&lt;/span&gt;-Jan-&lt;span style="color: #800080;"&gt;2012&lt;/span&gt;::&lt;span style="color: #800080;"&gt;10&lt;/span&gt;:&lt;span style="color: #800080;"&gt;35&lt;/span&gt;:&lt;span style="color: #800080;"&gt;21&lt;/span&gt; === %logger_guard 重建&lt;br /&gt;          &lt;span style="color: #008080;"&gt;supervisor:&lt;/span&gt; {local,log4erl_sup}&lt;br /&gt;             &lt;span style="color: #008080;"&gt;started:&lt;/span&gt; [{pid,&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;70&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;},&lt;br /&gt;                       {name,default_app},&lt;br /&gt;                       {mfargs,&lt;br /&gt;                           {logger_guard,start_link,&lt;br /&gt;                               [default_logger,file_appender,default_app,&lt;br /&gt;                                {conf,&lt;br /&gt;                                    [{dir,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;./log&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;},{level,debug}, {file,default_log},{type,size},&lt;br /&gt;                                     {max,&lt;span style="color: #800080;"&gt;1000000&lt;/span&gt;}, {suffix,log},{rotation,&lt;span style="color: #800080;"&gt;50&lt;/span&gt;},&lt;br /&gt;                                     {format,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt; %d %h:%m:%s.%i %l%n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;}]}]}},&lt;br /&gt;                       {restart_type,permanent},&lt;br /&gt;                       {shutdown,&lt;span style="color: #800080;"&gt;10000&lt;/span&gt;},&lt;br /&gt;                       {child_type,worker}]&lt;br /&gt;&lt;span style="color: #800080;"&gt;9&lt;/span&gt;&amp;gt; whereis(default_logger).       &lt;br /&gt;&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;69&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;10&lt;/span&gt;&amp;gt; is_process_alive(pid(&lt;span style="color: #800080;"&gt;0&lt;/span&gt;,&lt;span style="color: #800080;"&gt;70&lt;/span&gt;,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;)).   %这是新启动的logger_guard进程&lt;br /&gt;true&lt;br /&gt;&lt;span style="color: #800080;"&gt;11&lt;/span&gt;&amp;gt; exit(pid(&lt;span style="color: #800080;"&gt;0&lt;/span&gt;,&lt;span style="color: #800080;"&gt;70&lt;/span&gt;,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;),some_reason).   %向进程发送一个退出消息&lt;br /&gt;true&lt;br /&gt;&lt;br /&gt;=SUPERVISOR REPORT==== &lt;span style="color: #800080;"&gt;10&lt;/span&gt;-Jan-&lt;span style="color: #800080;"&gt;2012&lt;/span&gt;::&lt;span style="color: #800080;"&gt;11&lt;/span&gt;:&lt;span style="color: #800080;"&gt;07&lt;/span&gt;:&lt;span style="color: #800080;"&gt;51&lt;/span&gt; ===&lt;br /&gt;     &lt;span style="color: #008080;"&gt;Supervisor:&lt;/span&gt; {local,log4erl_sup}&lt;br /&gt;     &lt;span style="color: #008080;"&gt;Context:&lt;/span&gt;    child_terminated&lt;br /&gt;     &lt;span style="color: #008080;"&gt;Reason:&lt;/span&gt;     some_reason&lt;br /&gt;     &lt;span style="color: #008080;"&gt;Offender:&lt;/span&gt;   [{pid,&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;70&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;},&lt;br /&gt;                  {name,default_app},&lt;br /&gt;                  {mfargs,&lt;br /&gt;                      {logger_guard,start_link,&lt;br /&gt;                          [default_logger,file_appender,default_app,&lt;br /&gt;                           {conf,&lt;br /&gt;                               [{dir,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;./log&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;},{level,debug},{file,default_log},{type,size},{max,&lt;span style="color: #800080;"&gt;1000000&lt;/span&gt;},&lt;br /&gt;                                {suffix,log},{rotation,&lt;span style="color: #800080;"&gt;50&lt;/span&gt;},{format,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt; %d %h:%m:%s.%i %l%n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;}]}]}},&lt;br /&gt;                  {restart_type,permanent},&lt;br /&gt;                  {shutdown,&lt;span style="color: #800080;"&gt;10000&lt;/span&gt;},&lt;br /&gt;                  {child_type,worker}]&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;12&lt;/span&gt;&amp;gt;&lt;br /&gt;=PROGRESS REPORT==== &lt;span style="color: #800080;"&gt;10&lt;/span&gt;-Jan-&lt;span style="color: #800080;"&gt;2012&lt;/span&gt;::&lt;span style="color: #800080;"&gt;11&lt;/span&gt;:&lt;span style="color: #800080;"&gt;07&lt;/span&gt;:&lt;span style="color: #800080;"&gt;51&lt;/span&gt; ===&lt;br /&gt;          &lt;span style="color: #008080;"&gt;supervisor:&lt;/span&gt; {local,log4erl_sup}&lt;br /&gt;             &lt;span style="color: #008080;"&gt;started:&lt;/span&gt; [{pid,&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;76&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;},&lt;br /&gt;                       {name,default_app},&lt;br /&gt;                       {mfargs,&lt;br /&gt;                           {logger_guard,start_link,&lt;br /&gt;                               [default_logger,file_appender,default_app,&lt;br /&gt;                                {conf,&lt;br /&gt;                                    [{dir,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;./log&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;},{level,debug},{file,default_log},{type,size},{max,&lt;span style="color: #800080;"&gt;1000000&lt;/span&gt;},&lt;br /&gt;                                     {suffix,log},{rotation,&lt;span style="color: #800080;"&gt;50&lt;/span&gt;},{format,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt; %d %h:%m:%s.%i %l%n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;}]}]}},&lt;br /&gt;                       {restart_type,permanent},&lt;br /&gt;            {shutdown,&lt;span style="color: #800080;"&gt;10000&lt;/span&gt;},{child_type,worker}]&lt;br /&gt;&lt;span style="color: #800080;"&gt;12&lt;/span&gt;&amp;gt; is_process_alive(pid(&lt;span style="color: #800080;"&gt;0&lt;/span&gt;,&lt;span style="color: #800080;"&gt;70&lt;/span&gt;,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;)).&lt;br /&gt;false&lt;br /&gt;&lt;span style="color: #800080;"&gt;13&lt;/span&gt;&amp;gt; whereis(default_logger).  %退出消息广播对default_logger没有影响&lt;br /&gt;&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;69&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;14&lt;/span&gt;&amp;gt; whereis(log4erl_sup).&lt;br /&gt;&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;44&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;15&lt;/span&gt;&amp;gt; exit(whereis(log4erl_sup),some_reason).  % Supervisor 初始化的时候也会设置  process_flag(trap_exit, true),&lt;br /&gt;true&lt;br /&gt;&lt;span style="color: #800080;"&gt;16&lt;/span&gt;&amp;gt; whereis(log4erl_sup).&lt;br /&gt;&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;44&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;17&lt;/span&gt;&amp;gt; exit(whereis(log4erl_sup),kill).  %杀掉log4erl_sup 应用程序停止&lt;br /&gt;true&lt;br /&gt;&lt;br /&gt;=CRASH REPORT==== &lt;span style="color: #800080;"&gt;10&lt;/span&gt;-Jan-&lt;span style="color: #800080;"&gt;2012&lt;/span&gt;::&lt;span style="color: #800080;"&gt;13&lt;/span&gt;:&lt;span style="color: #800080;"&gt;26&lt;/span&gt;:&lt;span style="color: #800080;"&gt;23&lt;/span&gt; ===&lt;br /&gt;  &lt;span style="color: #008080;"&gt;crasher:&lt;/span&gt;&lt;br /&gt;    initial &lt;span style="color: #0000ff;"&gt;call&lt;/span&gt;: &lt;span style="color: #008080;"&gt;gen_event:&lt;/span&gt;init_it/&lt;span style="color: #800080;"&gt;6&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;pid:&lt;/span&gt; &amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;69&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;registered_name:&lt;/span&gt; default_logger&lt;br /&gt;    exception &lt;span style="color: #008080;"&gt;exit:&lt;/span&gt; killed&lt;br /&gt;      &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; function  &lt;span style="color: #008080;"&gt;gen_event:&lt;/span&gt;terminate_server/&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;ancestors:&lt;/span&gt; [log4erl_sup,&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;43&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;]&lt;br /&gt;    &lt;span style="color: #008080;"&gt;messages:&lt;/span&gt; [{&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;EXIT&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;76&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;,killed}]&lt;br /&gt;    &lt;span style="color: #008080;"&gt;links:&lt;/span&gt; [#Port&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;1891&lt;/span&gt;&amp;gt;,#Port&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;1885&lt;/span&gt;&amp;gt;]&lt;br /&gt;    &lt;span style="color: #008080;"&gt;dictionary:&lt;/span&gt; []&lt;br /&gt;    &lt;span style="color: #008080;"&gt;trap_exit:&lt;/span&gt; true&lt;br /&gt;    &lt;span style="color: #008080;"&gt;status:&lt;/span&gt; running&lt;br /&gt;    &lt;span style="color: #008080;"&gt;heap_size:&lt;/span&gt; &lt;span style="color: #800080;"&gt;610&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;stack_size:&lt;/span&gt; &lt;span style="color: #800080;"&gt;24&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;reductions:&lt;/span&gt; &lt;span style="color: #800080;"&gt;720&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #008080;"&gt;neighbours:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;18&lt;/span&gt;&amp;gt;&lt;br /&gt;=CRASH REPORT==== &lt;span style="color: #800080;"&gt;10&lt;/span&gt;-Jan-&lt;span style="color: #800080;"&gt;2012&lt;/span&gt;::&lt;span style="color: #800080;"&gt;13&lt;/span&gt;:&lt;span style="color: #800080;"&gt;26&lt;/span&gt;:&lt;span style="color: #800080;"&gt;23&lt;/span&gt; ===&lt;br /&gt;  &lt;span style="color: #008080;"&gt;crasher:&lt;/span&gt;&lt;br /&gt;    initial &lt;span style="color: #0000ff;"&gt;call&lt;/span&gt;: &lt;span style="color: #008080;"&gt;gen_event:&lt;/span&gt;init_it/&lt;span style="color: #800080;"&gt;6&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;pid:&lt;/span&gt; &amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;47&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;registered_name:&lt;/span&gt; mail_logger&lt;br /&gt;    exception &lt;span style="color: #008080;"&gt;exit:&lt;/span&gt; killed&lt;br /&gt;      &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; function  &lt;span style="color: #008080;"&gt;gen_event:&lt;/span&gt;terminate_server/&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;ancestors:&lt;/span&gt; [log4erl_sup,&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;43&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;]&lt;br /&gt;    &lt;span style="color: #008080;"&gt;messages:&lt;/span&gt; [{&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;EXIT&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;,&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;48&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;,killed}]&lt;br /&gt;    &lt;span style="color: #008080;"&gt;links:&lt;/span&gt; [#Port&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;546&lt;/span&gt;&amp;gt;]&lt;br /&gt;    &lt;span style="color: #008080;"&gt;dictionary:&lt;/span&gt; []&lt;br /&gt;    &lt;span style="color: #008080;"&gt;trap_exit:&lt;/span&gt; true&lt;br /&gt;    &lt;span style="color: #008080;"&gt;status:&lt;/span&gt; running&lt;br /&gt;    &lt;span style="color: #008080;"&gt;heap_size:&lt;/span&gt; &lt;span style="color: #800080;"&gt;377&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;stack_size:&lt;/span&gt; &lt;span style="color: #800080;"&gt;24&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;reductions:&lt;/span&gt; &lt;span style="color: #800080;"&gt;411&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #008080;"&gt;neighbours:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;18&lt;/span&gt;&amp;gt;&lt;br /&gt;=CRASH REPORT==== &lt;span style="color: #800080;"&gt;10&lt;/span&gt;-Jan-&lt;span style="color: #800080;"&gt;2012&lt;/span&gt;::&lt;span style="color: #800080;"&gt;13&lt;/span&gt;:&lt;span style="color: #800080;"&gt;26&lt;/span&gt;:&lt;span style="color: #800080;"&gt;25&lt;/span&gt; ===&lt;br /&gt;  &lt;span style="color: #008080;"&gt;crasher:&lt;/span&gt;&lt;br /&gt;    initial &lt;span style="color: #0000ff;"&gt;call&lt;/span&gt;: &lt;span style="color: #008080;"&gt;application_master:&lt;/span&gt;init/&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;pid:&lt;/span&gt; &amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;42&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;registered_name:&lt;/span&gt; []&lt;br /&gt;    exception &lt;span style="color: #008080;"&gt;exit:&lt;/span&gt; killed&lt;br /&gt;      &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; function  &lt;span style="color: #008080;"&gt;application_master:&lt;/span&gt;terminate/&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;ancestors:&lt;/span&gt; [&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;41&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;]&lt;br /&gt;    &lt;span style="color: #008080;"&gt;messages:&lt;/span&gt; []&lt;br /&gt;    &lt;span style="color: #008080;"&gt;links:&lt;/span&gt; [&amp;lt;&lt;span style="color: #800080;"&gt;0&lt;/span&gt;.&lt;span style="color: #800080;"&gt;6&lt;/span&gt;.&lt;span style="color: #800080;"&gt;0&lt;/span&gt;&amp;gt;]&lt;br /&gt;    &lt;span style="color: #008080;"&gt;dictionary:&lt;/span&gt; []&lt;br /&gt;    &lt;span style="color: #008080;"&gt;trap_exit:&lt;/span&gt; true&lt;br /&gt;    &lt;span style="color: #008080;"&gt;status:&lt;/span&gt; running&lt;br /&gt;    &lt;span style="color: #008080;"&gt;heap_size:&lt;/span&gt; &lt;span style="color: #800080;"&gt;610&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;stack_size:&lt;/span&gt; &lt;span style="color: #800080;"&gt;24&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #008080;"&gt;reductions:&lt;/span&gt; &lt;span style="color: #800080;"&gt;1555&lt;/span&gt;&lt;br /&gt;  &lt;span style="color: #008080;"&gt;neighbours:&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #800080;"&gt;18&lt;/span&gt;&amp;gt;&lt;br /&gt;=INFO REPORT==== &lt;span style="color: #800080;"&gt;10&lt;/span&gt;-Jan-&lt;span style="color: #800080;"&gt;2012&lt;/span&gt;::&lt;span style="color: #800080;"&gt;13&lt;/span&gt;:&lt;span style="color: #800080;"&gt;26&lt;/span&gt;:&lt;span style="color: #800080;"&gt;25&lt;/span&gt; ===&lt;br /&gt;    &lt;span style="color: #008080;"&gt;application:&lt;/span&gt; log4erl&lt;br /&gt;    &lt;span style="color: #008080;"&gt;exited:&lt;/span&gt; killed&lt;br /&gt;    &lt;span style="color: #008080;"&gt;type:&lt;/span&gt; temporary&lt;br /&gt;&lt;span style="color: #800080;"&gt;18&lt;/span&gt;&amp;gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;span&gt;&amp;nbsp;最后再贴一次log4erl项目的地址:&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a href="http://code.google.com/p/log4erl/"&gt;http://code.google.com/p/log4erl/&lt;/a&gt;,建议下载下来代码自己动手做一下上面的实验.&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;span&gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;span&gt;下一篇:&lt;a id="homepage1_HomePageDays_DaysList_DayItem_0_DayList_0_TitleUrl_0" href="http://www.cnblogs.com/me-sa/archive/2012/01/10/erlang0031.html"&gt;[Erlang 0031] Erlang Shell中的输出完整数据&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/me-sa/aggbug/2318086.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2012/01/10/erlang0030.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/me-sa/archive/2012/01/09/erlang0029.html</id><title type="text">[Erlang 0029] Erlang Inline编译</title><summary type="text">Erlang的编译器可以将Erlang模块中的函数进行内联编译,内联(inlining)的含义是把一个方法的调用替换成函数体并把参数替换成实际值.</summary><published>2012-01-09T05:40:00Z</published><updated>2012-01-09T05:40:00Z</updated><author><name>坚强2002</name><uri>http://www.cnblogs.com/me-sa/</uri></author><link rel="alternate" href="http://www.cnblogs.com/me-sa/archive/2012/01/09/erlang0029.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/me-sa/archive/2012/01/09/erlang0029.html"/><content type="html">&lt;p&gt;内联函数建议编译器将制定的函数体插入并取代每一处调用该函数的地方,从而节省了每一次函数调用带来的时间开支,选择内联函数时,必须要在程序占用空间和程序执行效率之间进行权衡,因为过多的对较为复杂的函数进行内联扩展将带来很大的存储资源开支.另外注意对于递归函数的内联扩展可能带来部分编译器的无穷编译.内联扩展是一种特别的用于消除调用函数时所造成的固有的时间消耗方法。一般用于能够快速执行的函数，因为在这种情况下函数调用的时间消耗显得更为突出。&lt;br /&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; --维基百科内联函数摘要&lt;/p&gt;&#xD;
&lt;p&gt;从维基百科的描述中可以看到内联函数解决的问题是:函数的调用时间比函数执行时间相当的时候,通过空间换时间,获得执行效率.实现角度Inlining是通过代码复制的方式节省进栈出栈的开销.Erlang的编译器可以将Erlang模块中的函数进行内联编译,内联(inlining)的含义是把一个方法的调用替换成函数体并把参数替换成实际值.&lt;br /&gt; Erlang内联不是默认值;必须明确指定compile选项( 形式: {inline,[{Name,Arity},...]} ) 或者在源代码使用-compile.&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;%%Example of explicit &lt;span style="color: #008080;"&gt;inlining:&lt;/span&gt;&lt;br /&gt;-compile({inline,[pi/&lt;span style="color: #800080;"&gt;0&lt;/span&gt;]}).&lt;br /&gt;pi() -&amp;gt; &lt;span style="color: #800080;"&gt;3&lt;/span&gt;.&lt;span style="color: #800080;"&gt;1416&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;%% Example of implicit &lt;span style="color: #008080;"&gt;inlining:&lt;/span&gt;&lt;br /&gt;-compile(inline).&lt;br /&gt;&lt;br /&gt;%% Aggressive inlining - will increase code size.&lt;br /&gt;-compile(inline).&lt;br /&gt;-compile({inline_size,&lt;span style="color: #800080;"&gt;100&lt;/span&gt;}).&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;如果一个函数被编译成inline,原始的函数还是会被保留,我们可以直接在erlang shell中调用这个方法.&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;-module(&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;).&lt;br /&gt;-compile(export_all).&lt;br /&gt;-compile({inline,[server_id/&lt;span style="color: #800080;"&gt;0&lt;/span&gt;]}).&lt;br /&gt;&lt;br /&gt;server_id() -&amp;gt;&lt;br /&gt;               &lt;span style="color: #800080;"&gt;2396&lt;/span&gt;.&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;内联编译不一定提高运行时的效率.例如内联可能增加Beam的栈消耗,对于递归函数调用这显然是有损性能的.{inline_size,Size}就是用来控制方法在多大程度上可以inline.Size默认值是24,这样inline代码与没有做inline的代码size相当,只有相当小的方法会被做inline.&lt;/p&gt;&#xD;
&lt;p&gt;那这个Size到底是指什么的大小呢?是代码函数?是代码个数?还是别的什么?我在erlangqa.org提了这个问题,得到了litaocheng的解答:&lt;/p&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;p&gt;http://www.erlangqa.com/?qa=100/inline_size-size-%E4%B8%AD%E7%9A%84size%E6%98%AF%E6%8C%87%E4%BB%80%E4%B9%88&lt;/p&gt;&#xD;
&lt;p&gt;请参考otp_src/compiler/src/cerl_inline.erl的weight/1函数。&lt;br /&gt;相应的Erlang表达式都有不同的权重。inline_size指的是函数汇编后的权重值。&lt;br /&gt;可以通过 erlc +\'S\' your.erl来得到汇编文件:your.S。&lt;/p&gt;&#xD;
&lt;p&gt;同时参考cerl_inline.erl文件中：当inline_size为30时，90%的情况下可以得到最大加速。inline_size为100-150时，98%的情况下可以最大优化。如果指定更大值，会使代码尺寸变大，性能反而受到影响。&lt;/p&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;按图索骥找到cerl_inline.erl weight/1的代码:&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('5aed5455-51f4-430f-99a8-bac4c62163ab')"&gt;&#xD;
&lt;div id="cnblogs_code_open_5aed5455-51f4-430f-99a8-bac4c62163ab" &gt;&#xD;
&lt;pre&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; default_effort() -&amp;gt; &lt;span style="color: #800080;"&gt;150&lt;/span&gt;.&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; default_size() -&amp;gt; &lt;span style="color: #800080;"&gt;24&lt;/span&gt;.&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; default_unroll() -&amp;gt; &lt;span style="color: #800080;"&gt;1&lt;/span&gt;.&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; %% Base costs/weights for different kinds of expressions. If these are&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; %% modified, the size limits above may have to be adjusted.&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; weight(var) -&amp;gt; &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;     % We count no cost for variable accesses.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; weight(values) -&amp;gt; &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;     % Value aggregates have no cost in themselves.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; weight(literal) -&amp;gt; &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;     % We assume efficient handling of constants.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; weight(data) -&amp;gt; &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;     % Base cost; add 1 per element.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; weight(element) -&amp;gt; &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;   % Cost of storing/fetching an element.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; weight(argument) -&amp;gt; &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;  % Cost of passing a function argument.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; weight(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;fun&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;) -&amp;gt; &lt;span style="color: #800080;"&gt;6&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;     % Base cost + average number of free vars.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; weight(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;let&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;) -&amp;gt; &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;     % Count no cost for let-bindings.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; weight(letrec) -&amp;gt; &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;    % Like a let-binding.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; weight(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;case&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;) -&amp;gt; &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;     % Case switches have no base cost.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; weight(clause) -&amp;gt; &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;    % Count one jump at the end of each clause body.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; weight(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;receive&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;) -&amp;gt; &lt;span style="color: #800080;"&gt;9&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;     % Initialization/cleanup cost.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; weight(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;try&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;) -&amp;gt; &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;     % Assume efficient implementation.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; weight(&lt;span style="color: #800000;"&gt;'&lt;/span&gt;&lt;span style="color: #800000;"&gt;catch&lt;/span&gt;&lt;span style="color: #800000;"&gt;'&lt;/span&gt;) -&amp;gt; &lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;     % See `try'.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; weight(apply) -&amp;gt; &lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;     % Average base cost: call/return.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; weight(&lt;span style="color: #0000ff;"&gt;call&lt;/span&gt;) -&amp;gt; &lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;      % Assume remote-calls as efficient as `apply'.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; weight(primop) -&amp;gt; &lt;span style="color: #800080;"&gt;2&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;    % Assume more efficient than `apply'.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; weight(binary) -&amp;gt; &lt;span style="color: #800080;"&gt;4&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;    % Initialisation base cost.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; weight(bitstr) -&amp;gt; &lt;span style="color: #800080;"&gt;3&lt;/span&gt;&lt;span style="color: #008000;"&gt;;&lt;/span&gt;&lt;span style="color: #008000;"&gt;    % Coding/decoding a value; like a primop.&lt;/span&gt;&lt;span style="color: #008000;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; weight(module) -&amp;gt; &lt;span style="color: #800080;"&gt;1&lt;/span&gt;.    % Like a letrec with a constant body&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;也就是说,不同的表达式有不同的权重值,Size既不是代码函数也不是函数个数,而是依赖于该权重值.这里我不再继续跟进了,cerl_inline.erl的注释提供了详细的信息:&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;div&gt;&lt;span&gt;Normal execution times for inlining are between 0.1 and 0.3 seconds&amp;nbsp;(on the author's current equipment). The default effort limit of 150&amp;nbsp;is high enough that most normal programs never hit the limit even&amp;nbsp;once, and for difficult programs, it generally keeps the execution&amp;nbsp;times below 2-5 seconds. Using an effort counter of 1000 will thus&amp;nbsp;have no further effect on most programs, but some programs may take&amp;nbsp;as much as 10 seconds or more. Effort counts larger than 2500 have&amp;nbsp;never been observed even on very ill-conditioned programs.&lt;br /&gt;&lt;br /&gt;&#xD;
Size limits between 6 and 18 tend to actually shrink the code,&amp;nbsp;because of the simplifications made possible by inlining. A limit of&amp;nbsp;16 seems to be optimal for this purpose, often shrinking the&amp;nbsp;executable code by up to 10%. Size limits between 18 and 30 generally&amp;nbsp;give the same code size as if no inlining was done (i.e., code&amp;nbsp;duplication balances out the simplifications at these levels). A size&amp;nbsp;limit between 1 and 5 tends to inline small functions and propagate&amp;nbsp;constants, but does not cause much simplifications do be done, so the&amp;nbsp;net effect will be a slight increase in code size. For size limits&amp;nbsp;above 30, the executable code size tends to increase with about 10%&amp;nbsp;per 100 units, with some variations depending on the sizes of&amp;nbsp;functions in the source code.&lt;br /&gt;&lt;br /&gt;&#xD;
Typically, about 90% of the maximum speedup achievable is already&amp;nbsp;reached using a size limit of 30, and 98% is reached at limits around&amp;nbsp;100-150; there is rarely any point in letting the code size increase&amp;nbsp;by more than 10-15%. If too large functions are inlined, cache&amp;nbsp;effects will slow the program down.&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;div&gt;&lt;span&gt;感兴趣的可以找到原始论文看下,论文地址:&amp;nbsp;"Fast and Effective Procedure Inlining", International Static Analysis Symposium 1997&amp;nbsp;&amp;nbsp;&lt;a href="http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.54.2438"&gt;http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.54.2438&lt;/a&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;算法不跟进,但是实验要做的,就按照litaocheng建议的方法,我做了一个这样的demo,写一个简单的方法,这个方法在另一个方法里面被多次调用(代码如下).我是在windows环境中使用,在shell中使用命令c(test,['S']).得到assembler code文件.&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;-module(&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;).&lt;br /&gt;-export([get_name/&lt;span style="color: #800080;"&gt;0&lt;/span&gt;, show/&lt;span style="color: #800080;"&gt;1&lt;/span&gt;]).&lt;br /&gt;&lt;br /&gt;get_name() -&amp;gt;&lt;br /&gt;     &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;This is Test Module&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;show(A) -&amp;gt;&lt;br /&gt;     A=get_name(),&lt;br /&gt;     A=get_name(),&lt;br /&gt;     A=get_name(),&lt;br /&gt;     A=get_name(),&lt;br /&gt;     A=get_name(),&lt;br /&gt;     A=get_name(),&lt;br /&gt;     &lt;span style="color: #008080;"&gt;io:&lt;/span&gt;format(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;This is ~p ~n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,[A]).&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;生成的assembler code文件如下:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;{module, &lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;}.  %% version = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;{exports, [{get_name,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},{module_info,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},{module_info,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;},{show,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}]}.&lt;br /&gt;&lt;br /&gt;{attributes, []}.&lt;br /&gt;&lt;br /&gt;{labels, &lt;span style="color: #800080;"&gt;15&lt;/span&gt;}.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;{function, get_name, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;2&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;22&lt;/span&gt;}]}.&lt;br /&gt;    {func_info,{atom,&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;},{atom,get_name},&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;}.&lt;br /&gt;    {move,{literal,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;This is Test Module&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;},{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;    return.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;{function, show, &lt;span style="color: #800080;"&gt;1&lt;/span&gt;, &lt;span style="color: #800080;"&gt;4&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;3&lt;/span&gt;}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;25&lt;/span&gt;}]}.&lt;br /&gt;    {func_info,{atom,&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;},{atom,show},&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;4&lt;/span&gt;}.&lt;br /&gt;    {allocate,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}.&lt;br /&gt;    {move,{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},{y,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;26&lt;/span&gt;}]}.&lt;br /&gt;    {&lt;span style="color: #0000ff;"&gt;call&lt;/span&gt;,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;,{f,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;}}.&lt;br /&gt;    {&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;,is_eq_exact,{f,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;},[{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},{y,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}]}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;27&lt;/span&gt;}]}.&lt;br /&gt;    {&lt;span style="color: #0000ff;"&gt;call&lt;/span&gt;,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;,{f,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;}}.&lt;br /&gt;    {&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;,is_eq_exact,{f,&lt;span style="color: #800080;"&gt;6&lt;/span&gt;},[{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},{y,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}]}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;28&lt;/span&gt;}]}.&lt;br /&gt;    {&lt;span style="color: #0000ff;"&gt;call&lt;/span&gt;,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;,{f,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;}}.&lt;br /&gt;    {&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;,is_eq_exact,{f,&lt;span style="color: #800080;"&gt;7&lt;/span&gt;},[{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},{y,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}]}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;29&lt;/span&gt;}]}.&lt;br /&gt;    {&lt;span style="color: #0000ff;"&gt;call&lt;/span&gt;,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;,{f,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;}}.&lt;br /&gt;    {&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;,is_eq_exact,{f,&lt;span style="color: #800080;"&gt;8&lt;/span&gt;},[{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},{y,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}]}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;30&lt;/span&gt;}]}.&lt;br /&gt;    {&lt;span style="color: #0000ff;"&gt;call&lt;/span&gt;,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;,{f,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;}}.&lt;br /&gt;    {&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;,is_eq_exact,{f,&lt;span style="color: #800080;"&gt;9&lt;/span&gt;},[{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},{y,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}]}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;31&lt;/span&gt;}]}.&lt;br /&gt;    {&lt;span style="color: #0000ff;"&gt;call&lt;/span&gt;,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;,{f,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;}}.&lt;br /&gt;    {&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;,is_eq_exact,{f,&lt;span style="color: #800080;"&gt;10&lt;/span&gt;},[{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},{y,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}]}.&lt;br /&gt;    {test_heap,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}.&lt;br /&gt;    {put_list,{y,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},nil,{x,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}}.&lt;br /&gt;    {move,{literal,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;This is ~p ~n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;},{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;32&lt;/span&gt;}]}.&lt;br /&gt;    {call_ext_last,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;,{extfunc,io,format,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;},&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;26&lt;/span&gt;}]}.&lt;br /&gt;    {badmatch,{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;6&lt;/span&gt;}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;27&lt;/span&gt;}]}.&lt;br /&gt;    {badmatch,{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;7&lt;/span&gt;}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;28&lt;/span&gt;}]}.&lt;br /&gt;    {badmatch,{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;8&lt;/span&gt;}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;29&lt;/span&gt;}]}.&lt;br /&gt;    {badmatch,{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;9&lt;/span&gt;}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;30&lt;/span&gt;}]}.&lt;br /&gt;    {badmatch,{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;10&lt;/span&gt;}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;31&lt;/span&gt;}]}.&lt;br /&gt;    {badmatch,{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;{function, module_info, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;12&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;11&lt;/span&gt;}.&lt;br /&gt;    {line,[]}.&lt;br /&gt;    {func_info,{atom,&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;},{atom,module_info},&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;12&lt;/span&gt;}.&lt;br /&gt;    {move,{atom,&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;},{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;    {line,[]}.&lt;br /&gt;    {call_ext_only,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,{extfunc,erlang,get_module_info,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}}.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;{function, module_info, &lt;span style="color: #800080;"&gt;1&lt;/span&gt;, &lt;span style="color: #800080;"&gt;14&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;13&lt;/span&gt;}.&lt;br /&gt;    {line,[]}.&lt;br /&gt;    {func_info,{atom,&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;},{atom,module_info},&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;14&lt;/span&gt;}.&lt;br /&gt;    {move,{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},{x,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}}.&lt;br /&gt;    {move,{atom,&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;},{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;    {line,[]}.&lt;br /&gt;    {call_ext_only,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;,{extfunc,erlang,get_module_info,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;}}.&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;添加了inline选项之后的结果,这个demo比较变态生成的代码效果也比较明显:&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;{module, &lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;}.  %% version = &lt;span style="color: #800080;"&gt;0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;{exports, [{get_name,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},{module_info,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},{module_info,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;},{show,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}]}.&lt;br /&gt;&lt;br /&gt;{attributes, []}.&lt;br /&gt;&lt;br /&gt;{labels, &lt;span style="color: #800080;"&gt;10&lt;/span&gt;}.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;{function, get_name, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;2&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;23&lt;/span&gt;}]}.&lt;br /&gt;    {func_info,{atom,&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;},{atom,get_name},&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;}.&lt;br /&gt;    {move,{literal,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;This is Test Module&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;},{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;    return.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;{function, show, &lt;span style="color: #800080;"&gt;1&lt;/span&gt;, &lt;span style="color: #800080;"&gt;4&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;3&lt;/span&gt;}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;26&lt;/span&gt;}]}.&lt;br /&gt;    {func_info,{atom,&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;},{atom,show},&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;4&lt;/span&gt;}.&lt;br /&gt;    {&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;,is_eq_exact,{f,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;},[{literal,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;This is Test Module&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;},{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}]}.&lt;br /&gt;    {test_heap,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}.&lt;br /&gt;    {put_list,{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},nil,{x,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}}.&lt;br /&gt;    {move,{literal,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;This is ~p ~n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;},{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;33&lt;/span&gt;}]}.&lt;br /&gt;    {call_ext_only,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;,{extfunc,io,format,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;}}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;}.&lt;br /&gt;    {line,[{location,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;test.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800080;"&gt;27&lt;/span&gt;}]}.&lt;br /&gt;    {badmatch,{literal,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;This is Test Module&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;}}.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;{function, module_info, &lt;span style="color: #800080;"&gt;0&lt;/span&gt;, &lt;span style="color: #800080;"&gt;7&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;6&lt;/span&gt;}.&lt;br /&gt;    {line,[]}.&lt;br /&gt;    {func_info,{atom,&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;},{atom,module_info},&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;7&lt;/span&gt;}.&lt;br /&gt;    {move,{atom,&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;},{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;    {line,[]}.&lt;br /&gt;    {call_ext_only,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,{extfunc,erlang,get_module_info,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}}.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;{function, module_info, &lt;span style="color: #800080;"&gt;1&lt;/span&gt;, &lt;span style="color: #800080;"&gt;9&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;8&lt;/span&gt;}.&lt;br /&gt;    {line,[]}.&lt;br /&gt;    {func_info,{atom,&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;},{atom,module_info},&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}.&lt;br /&gt;  {label,&lt;span style="color: #800080;"&gt;9&lt;/span&gt;}.&lt;br /&gt;    {move,{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;},{x,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;}}.&lt;br /&gt;    {move,{atom,&lt;span style="color: #0000ff;"&gt;test&lt;/span&gt;},{x,&lt;span style="color: #800080;"&gt;0&lt;/span&gt;}}.&lt;br /&gt;    {line,[]}.&lt;br /&gt;    {call_ext_only,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;,{extfunc,erlang,get_module_info,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;}}.&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div&gt;&lt;span&gt;&lt;span&gt;官方文档:&amp;nbsp;&lt;a href="http://www.erlang.org/doc/man/compile.html"&gt;http://www.erlang.org/doc/man/compile.html&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;Erlang Assembly Code处于&amp;nbsp;not documented的状态,下面有两篇相关的文章:&lt;/div&gt;&#xD;
&lt;div&gt;Howto dump Core Erlang and assembly&amp;nbsp;&amp;nbsp;&lt;a href="http://untroubled.be/docs/erlang/howto_dump_core_erlang_and_assembly.html#1"&gt;http://untroubled.be/docs/erlang/howto_dump_core_erlang_and_assembly.html&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div&gt;How to modify Erlang assembly? Are any resources available? &amp;nbsp;&lt;a href="http://stackoverflow.com/questions/7935054/how-to-modify-erlang-assembly-are-any-resources-available"&gt;http://stackoverflow.com/questions/7935054/how-to-modify-erlang-assembly-are-any-resources-available&lt;/a&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;/div&gt;&lt;img src="http://www.cnblogs.com/me-sa/aggbug/2317018.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2012/01/09/erlang0029.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/me-sa/archive/2012/01/04/erlang0028.html</id><title type="text">[Erlang 0028] Erlang atom</title><summary type="text">Erlang中atom数据类型能够做的唯一的运算就是比较,它不参与垃圾回收,因而在搞崩Erlang的各种方法中无节制使用原子名列前茅.</summary><published>2012-01-04T07:57:00Z</published><updated>2012-01-04T07:57:00Z</updated><author><name>坚强2002</name><uri>http://www.cnblogs.com/me-sa/</uri></author><link rel="alternate" href="http://www.cnblogs.com/me-sa/archive/2012/01/04/erlang0028.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/me-sa/archive/2012/01/04/erlang0028.html"/><content type="html">&lt;div&gt;&lt;span&gt;&amp;nbsp; &amp;nbsp; Erlang中atom数据类型能够做的唯一的运算就是比较;在erlang中模块名和方法名都是原子; Erlang&amp;nbsp;M-F-A方法调用可以做的非常灵活,我们在shell里面操练一下:&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;Eshell V5.&lt;span style="color: #800080;"&gt;9&lt;/span&gt;  (abort with ^G)&lt;br /&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;gt; &lt;span style="color: #008080;"&gt;lists:&lt;/span&gt;seq(&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;).&lt;br /&gt;[&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;,&lt;span style="color: #800080;"&gt;3&lt;/span&gt;,&lt;span style="color: #800080;"&gt;4&lt;/span&gt;,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;]&lt;br /&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;gt; L=lists.&lt;br /&gt;lists&lt;br /&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&amp;gt; S=seq.&lt;br /&gt;seq&lt;br /&gt;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&amp;gt; &lt;span style="color: #008080;"&gt;L:&lt;/span&gt;S(&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;).&lt;br /&gt;[&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;,&lt;span style="color: #800080;"&gt;3&lt;/span&gt;,&lt;span style="color: #800080;"&gt;4&lt;/span&gt;,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;]&lt;br /&gt;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;&amp;gt; &lt;span style="color: #008080;"&gt;L:&lt;/span&gt;seq(&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;).&lt;br /&gt;[&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;,&lt;span style="color: #800080;"&gt;3&lt;/span&gt;,&lt;span style="color: #800080;"&gt;4&lt;/span&gt;,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;]&lt;br /&gt;&lt;span style="color: #800080;"&gt;6&lt;/span&gt;&amp;gt; L2=list_to_atom(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;list&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt; ++&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;s&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).&lt;br /&gt;lists&lt;br /&gt;&lt;span style="color: #800080;"&gt;7&lt;/span&gt;&amp;gt; &lt;span style="color: #008080;"&gt;L2:&lt;/span&gt;seq(&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;).&lt;br /&gt;[&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;,&lt;span style="color: #800080;"&gt;3&lt;/span&gt;,&lt;span style="color: #800080;"&gt;4&lt;/span&gt;,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;]&lt;br /&gt;&lt;span style="color: #800080;"&gt;8&lt;/span&gt;&amp;gt; apply(list_to_atom(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;li&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;sts&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;),seq,[&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;]).&lt;br /&gt;[&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;2&lt;/span&gt;,&lt;span style="color: #800080;"&gt;3&lt;/span&gt;,&lt;span style="color: #800080;"&gt;4&lt;/span&gt;,&lt;span style="color: #800080;"&gt;5&lt;/span&gt;]&lt;br /&gt;&lt;span style="color: #800080;"&gt;9&lt;/span&gt;&amp;gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;br /&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;Erlang atom&lt;a href="http://www.cnblogs.com/me-sa/archive/2011/11/13/erlang0014.html"&gt;不参与垃圾回收&lt;/a&gt;,一旦创建就不会被移除掉;一旦超出atom的数量限制(默认是1048576) VM就会终止掉.对于一个会持续运行很久的系统,把任意字符串转成atom是很危险的,内存会慢慢被吃光.如果使用的原子是在预期范围内的,比如协议模块的名称,那么可以使用list_to_existing_atom来进行防范,这个方法所产出的atom必须是之前已经创建过的.&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;%% list_to_existing_atom demo&lt;br /&gt; &lt;br /&gt;Eshell V5.&lt;span style="color: #800080;"&gt;9&lt;/span&gt;  (abort with ^G)&lt;br /&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;gt; list_to_existing_atom(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;player_1&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).&lt;br /&gt;** exception &lt;span style="color: #008080;"&gt;error:&lt;/span&gt; bad argument              %尝试调用 list_to_existing_atom(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;player_1&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).由于player_1的原子之前没有被创建过&lt;br /&gt;     &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; function  list_to_existing_atom/&lt;span style="color: #800080;"&gt;1&lt;/span&gt;        %这里报错了 异常是bad argument&lt;br /&gt;        called as list_to_existing_atom(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;player_1&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;gt; list_to_atom(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;player_1&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).                      %创建一下player_1&lt;br /&gt;player_1&lt;br /&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&amp;gt; list_to_existing_atom(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;player_1&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).          %再次调用list_to_existing_atom就是对的了&lt;br /&gt;player_1&lt;br /&gt;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&amp;gt; list_to_existing_atom(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;player_2&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).          &lt;br /&gt;** exception &lt;span style="color: #008080;"&gt;error:&lt;/span&gt; bad argument&lt;br /&gt;     &lt;span style="color: #0000ff;"&gt;in&lt;/span&gt; function  list_to_existing_atom/&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&lt;br /&gt;        called as list_to_existing_atom(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;player_2&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;)&lt;br /&gt;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;&amp;gt; player_2.                                             %也可以这样创建原子 &lt;br /&gt;player_2&lt;br /&gt;&lt;span style="color: #800080;"&gt;6&lt;/span&gt;&amp;gt; list_to_existing_atom(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;player_2&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).          %这时调用也是对的&lt;br /&gt;player_2&lt;br /&gt;&lt;span style="color: #800080;"&gt;7&lt;/span&gt;&amp;gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;br /&gt;我们可以使用&lt;span data-mce-=""&gt;&lt;span data-mce-=""&gt;&lt;span data-mce-=""&gt;string:&lt;/span&gt;tokens( binary_to_list(&lt;span data-mce-=""&gt;erlang:&lt;/span&gt;system_info(info)),&lt;span data-mce-=""&gt;"&lt;/span&gt;&lt;span data-mce-=""&gt;\n&lt;/span&gt;&lt;span data-mce-=""&gt;"&lt;/span&gt;)在shell中看一下atom的使用情况,输出的片段中恰好包含了原子内存使用的情况,当前数量和数量限制;想看完整的输出?&lt;a href="http://www.cnblogs.com/me-sa/archive/2012/01/10/erlang0031.html"&gt;穿越到这里&lt;/a&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;%% list_to_atom demo limit&lt;br /&gt;&lt;br /&gt;Eshell V5.&lt;span style="color: #800080;"&gt;9&lt;/span&gt;  (abort with ^G)&lt;br /&gt;&lt;span style="color: #800080;"&gt;1&lt;/span&gt;&amp;gt;  &lt;span style="color: #008080;"&gt;string:&lt;/span&gt;tokens( binary_to_list(&lt;span style="color: #008080;"&gt;erlang:&lt;/span&gt;system_info(info)),&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).&lt;br /&gt;[&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=memory&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;total: 4331920&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;processes: 438877&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;processes_used: 438862&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;system: 3893043&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;atom: 146321&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;atom_used: 119102&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;binary: 327936&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;code: 1929551&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;ets: 123308&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=hash_table:atom_tab&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 4813&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;used: 3508&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;objs: 6410&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;depth: 7&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=index_table:atom_tab&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 7168&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;limit: 1048576&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;entries: 6410&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=hash_table:module_code&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 97&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;used: 52&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;objs: 72&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;depth: 4&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=index_table:module_code&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 1024&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;limit: 65536&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;entries: 72&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;[...]|...]&lt;br /&gt;&lt;span style="color: #800080;"&gt;2&lt;/span&gt;&amp;gt;  [list_to_atom(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;player_&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++integer_to_list(Item)) || Item &amp;lt;- &lt;span style="color: #008080;"&gt;lists:&lt;/span&gt;seq(&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;1000000&lt;/span&gt;) ].&lt;br /&gt;[player_1,player_2,player_3,player_4,player_5,player_6,&lt;br /&gt;player_7,player_8,player_9,player_10,player_11,player_12,&lt;br /&gt;player_13,player_14,player_15,player_16,player_17,player_18,&lt;br /&gt;player_19,player_20,player_21,player_22,player_23,player_24,&lt;br /&gt;player_25,player_26,player_27,player_28,player_29|...]&lt;br /&gt;&lt;span style="color: #800080;"&gt;3&lt;/span&gt;&amp;gt;  &lt;span style="color: #008080;"&gt;string:&lt;/span&gt;tokens( binary_to_list(&lt;span style="color: #008080;"&gt;erlang:&lt;/span&gt;system_info(info)),&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).&lt;br /&gt;[&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=memory&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;total: 93955448&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;processes: 37830214&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;processes_used: 37830214&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;system: 56125234&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;atom: 20296629&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;atom_used: 20279627&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;binary: 360656&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;code: 1965264&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;ets: 124260&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=hash_table:atom_tab&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 823117&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;used: 627221&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;objs: 1006479&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;depth: 7&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=index_table:atom_tab&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 1006592&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;limit: 1048576&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;entries: 1006479&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=hash_table:module_code&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 97&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;used: 54&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;objs: 74&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;depth: 4&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=index_table:module_code&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 1024&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;limit: 65536&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;entries: 74&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;[...]|...]&lt;br /&gt;&lt;span style="color: #800080;"&gt;4&lt;/span&gt;&amp;gt;  [list_to_atom(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;player_&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++integer_to_list(Item)) || Item &amp;lt;- &lt;span style="color: #008080;"&gt;lists:&lt;/span&gt;seq(&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,&lt;span style="color: #800080;"&gt;1000000&lt;/span&gt;) ].&lt;br /&gt;[player_1,player_2,player_3,player_4,player_5,player_6,&lt;br /&gt;player_7,player_8,player_9,player_10,player_11,player_12,&lt;br /&gt;player_13,player_14,player_15,player_16,player_17,player_18,&lt;br /&gt;player_19,player_20,player_21,player_22,player_23,player_24,&lt;br /&gt;player_25,player_26,player_27,player_28,player_29|...]&lt;br /&gt;&lt;span style="color: #800080;"&gt;5&lt;/span&gt;&amp;gt;  &lt;span style="color: #008080;"&gt;string:&lt;/span&gt;tokens( binary_to_list(&lt;span style="color: #008080;"&gt;erlang:&lt;/span&gt;system_info(info)),&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).&lt;br /&gt;[&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=memory&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;total: 98839096&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;processes: 42712630&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;processes_used: 42712630&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;system: 56126466&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;atom: 20296629&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;atom_used: 20279627&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;binary: 361888&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;code: 1965264&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;ets: 124260&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=hash_table:atom_tab&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 823117&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;used: 627221&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;objs: 1006479&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;depth: 7&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=index_table:atom_tab&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 1006592&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;limit: 1048576&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,    %注意再次调用的时候这里没有变化&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;entries: 1006479&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=hash_table:module_code&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 97&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;used: 54&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;objs: 74&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;depth: 4&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;=index_table:module_code&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;size: 1024&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;limit: 65536&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;entries: 74&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;[...]|...]&lt;br /&gt;&lt;span style="color: #800080;"&gt;6&lt;/span&gt;&amp;gt;&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;我们挑战一下atom的数量上限,&lt;span&gt;&amp;nbsp; [list_to_atom("player_"++integer_to_list(Item)) || Item &amp;lt;- lists:seq(1,100000000) ].只要运行这个就可以了,不久我们就看到下面的提示:&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2012/17329/2012010415470292.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;所以在&lt;a href="http://prog21.dadgum.com/43.html"&gt;How to Crash Erlang&lt;/a&gt; 一文中,无节制使用atom名列前茅:&lt;/p&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;p&gt;&lt;strong&gt;Run out of atoms.&lt;/strong&gt;&amp;nbsp;Atoms in Erlang are analogous to symbols in Lisp--that is, symbolic, non-string identifiers that make code more readable, like&amp;nbsp;&lt;tt&gt;green&lt;/tt&gt;&amp;nbsp;or&amp;nbsp;&lt;tt&gt;unknown_value&lt;/tt&gt;--with one exception. Atoms in Erlang are not garbage collected. Once an atom has been created, it lives as long as the Erlang node is running. An easy way to crash the Erlang virtual machine is to loop from 1 to some large number, calling&amp;nbsp;&lt;tt&gt;integer_to_list&lt;/tt&gt;&amp;nbsp;and then&amp;nbsp;&lt;tt&gt;list_to_atom&lt;/tt&gt;&amp;nbsp;on the current loop index. The atom table will fill up with unused entries, eventually bringing the runtime system to halt.&amp;nbsp;&lt;br /&gt;&lt;br /&gt;Why is this is allowed? Because garbage collecting atoms would involve a pass over all data in all processes, something the garbage collector&amp;nbsp;&lt;a href="http://prog21.dadgum.com/16.html"&gt;was specifically designed&lt;/a&gt;&amp;nbsp;to avoid. And in practice, running out of atoms will only happen if you write code that's generating new atoms on the fly.&amp;nbsp;&lt;/p&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;img src="file:///C:/Users/ADMINI~1/AppData/Local/Temp/1/enhtmlclip/Image.png" alt="" /&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/me-sa/aggbug/2312130.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2012/01/04/erlang0028.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/me-sa/archive/2011/12/31/erlang0027.html</id><title type="text">[Erlang 0027] Using Record in Erlang Shell</title><summary type="text">《[Erlang 0006] Erlang中的record与宏》一文中我们提到过Record是一个编译时的功能,在Erlang VM中并没有专门的数据类型.如何在Erlang Shell中使用Record呢?本文给出了五种方法.</summary><published>2011-12-31T05:34:00Z</published><updated>2011-12-31T05:34:00Z</updated><author><name>坚强2002</name><uri>http://www.cnblogs.com/me-sa/</uri></author><link rel="alternate" href="http://www.cnblogs.com/me-sa/archive/2011/12/31/erlang0027.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/me-sa/archive/2011/12/31/erlang0027.html"/><content type="html">&lt;p&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2011/07/20/erlang0006.html" target="_blank"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;[Erlang 0006] Erlang中的record与宏&lt;/a&gt; 中我们提到过Record是一个编译时的功能,在Erlang VM中并没有专门的数据类型.在线上解决问题有时候会遇到要在shell中使用record,那么就有两个选择:1.在shell中构造record定义,如果能构造record有了record的定义编写ets:match的匹配模式就方便多了; 2.直接使用record对应的tuple结构;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;方法一 使用rd命令&lt;/strong&gt; &lt;br /&gt; Eshell V5.9 (abort with ^G)&lt;br /&gt;1&amp;gt; rd(film ,{ director, actor, type, name,imdb}).&lt;br /&gt;film&lt;br /&gt;2&amp;gt; F =#film{}.&lt;br /&gt;#film{director = undefined,actor = undefined,&lt;br /&gt; type = undefined,name = undefined,imdb = undefined}&lt;br /&gt;3&amp;gt; F#film.type.&lt;br /&gt;undefined&lt;br /&gt;4&amp;gt; F#film.type=23.&lt;br /&gt;* 1: illegal pattern&lt;br /&gt;5&amp;gt; F2 =F#film{type=23}.&lt;br /&gt;#film{director = undefined,actor = undefined,type = 23,&lt;br /&gt; name = undefined,imdb = undefined}&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;方法二使用rr命令&lt;/strong&gt;&lt;br /&gt;rr命令可以加载模块中的record定义,我们把record放在一个模块中:&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;-module(records).&lt;br /&gt;-record(book,{name, id, item01, item02, item03, item04, item05, item06, item07, item08, item09, item10 } ).&lt;br /&gt;-record(film ,{ director, actor, type, name,imdb}).&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;&lt;br /&gt;我们在shell中编译并尝试加载其中的record:&lt;br /&gt;Eshell V5.9 (abort with ^G)&lt;br /&gt;1&amp;gt; c(records).&lt;br /&gt;records.erl:2: Warning: record book is unused&lt;br /&gt;records.erl:19: Warning: record film is unused&lt;br /&gt;{ok,records}&lt;br /&gt;2&amp;gt; rr(records).&lt;br /&gt;[book,film]&lt;br /&gt;3&amp;gt; F =#film{}.&lt;br /&gt;#film{director = undefined,actor = undefined,&lt;br /&gt; type = undefined,name = undefined,imdb = undefined}&lt;br /&gt;4&amp;gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;&lt;strong&gt;方法三 最方便的方案 user_default&lt;/strong&gt;&lt;/p&gt;&#xD;
&lt;p&gt;上面两种方法一种是手工定义,一种是手工加载定义,有更理想的方案么?有!&lt;br /&gt;仔细阅读一下Erlang shell的文档,我们可以看到下面这段: http://www.erlang.org/documentation/doc-5.4.12/lib/stdlib-1.13.11/doc/html/shell.html&lt;/p&gt;&#xD;
&lt;blockquote style='border:2px solid #EFEFEF;color:#333333;padding:5px 10px;'&gt;&#xD;
&lt;p&gt;If a command (local function call) is not recognized by the shell, an attempt is first made to find the function in the module user_default, where customized local commands can be placed. If found, then the function is evaluated. Otherwise, an attempt is made to evaluate the function in the module shell_default. The module user_default must be explicitly loaded.&lt;/p&gt;&#xD;
&lt;p&gt;There is some support for reading and printing records in the shell. During compilation record expressions are translated to tuple expressions. In runtime it is not known whether a tuple actually represents a record. Nor are the record definitions used by compiler available at runtime. So in order to read the record syntax and print tuples as records when possible, record definitions have to be maintained by the shell itself. The shell commands for reading, defining, forgetting, listing, and printing records are described below. Note that each job has its own set of record definitions. To facilitate matters record definitions in the modules shell_default and user_default (if loaded) are read each time a new job is started.&lt;/p&gt;&#xD;
&lt;/blockquote&gt;&#xD;
&lt;p&gt;我们就使用user_default来解决这个问题!!!我们准备一下测试的文件:&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;"&gt;&#xD;
&lt;pre&gt;%% &lt;span style="color: #008080;"&gt;File:&lt;/span&gt; records.hrl&lt;br /&gt;-record(book,{ name, id, item01, item02, item03, item04, item05, item06, item07, item08, item09, item10 } ).&lt;br /&gt;-record(film ,{ director, actor, type, name,imdb}).&lt;br /&gt;-record(foo,{ id, name,bar}).&lt;br /&gt;&lt;br /&gt;%% &lt;span style="color: #008080;"&gt;File:&lt;/span&gt; user_default.erl&lt;br /&gt;-module(user_default).&lt;br /&gt;-include(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;records.hrl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).&lt;br /&gt;-compile(export_all).&lt;br /&gt;&lt;br /&gt;get_meta() -&amp;gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;user_default:&lt;/span&gt;module_info().&lt;br /&gt;&lt;br /&gt;get_timestamp() -&amp;gt;&lt;br /&gt;{M, S, _} = &lt;span style="color: #008080;"&gt;erlang:&lt;/span&gt;now(), &lt;br /&gt;M * &lt;span style="color: #800080;"&gt;1000000&lt;/span&gt; + S.&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;编译一下user_default.erl,编译之后我们启动Erlang Shell,可以看到不仅record已经加载了,而且user_default中定义的方法也可以直接访问.&lt;/p&gt;&#xD;
&lt;p&gt;Eshell V5.9 (abort with ^G)&lt;br /&gt;1&amp;gt; rl(). %%&amp;nbsp;在shell中可以使用rl()查看已经定义的record.&amp;nbsp;&lt;br /&gt;-record(book,{name, id, item01, item02, item03, item04, item05, item06, item07, item08, item09, item10 } ).&lt;br /&gt;-record(film,{director,actor,type,name,imdb}).&lt;br /&gt;-record(foo,{id,name,bar}).&lt;br /&gt;ok&lt;br /&gt;2&amp;gt; get_timestamp().&lt;br /&gt;1325308014&lt;br /&gt;3&amp;gt; F=foo#{}.&lt;br /&gt;* 1: syntax error before: '{'&lt;br /&gt;3&amp;gt; F=#foo{}.&lt;br /&gt;#foo{id = undefined,name = undefined,bar = undefined}&lt;br /&gt;4&amp;gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;方法四 不定义直接使用tuple&lt;/strong&gt;&lt;br /&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2011/07/20/erlang0006.html"&gt;[Erlang 0006] Erlang中的record与宏&lt;/a&gt; 我们说过record在Erlang的内部实现是还是一个tuple.在shell中我们可以使用等效的tuple.&lt;br /&gt;4&amp;gt; F2 =#film{director=2012}.&lt;br /&gt;#film{director = 2012,actor = undefined,type = undefined,&lt;br /&gt; name = undefined,imdb = undefined}&lt;br /&gt;5&amp;gt; F2 == {film , 2012, undefined, undefined, undefined, undefined} .&lt;br /&gt;true&lt;/p&gt;&#xD;
&lt;p&gt;&lt;strong&gt;方法五 Match Specifications And Records (Dynamically!)&lt;/strong&gt;&lt;br /&gt; 这是trapexit上提供的一个解决方案,稍微绕一点,主要是{ok,Tree}=epp:parse_file("myheader.hrl",["./"],[])解析头文件进行预处理,然后生成reocrd的元数据module文件,再利用工具类来动态生成match specification;&lt;/p&gt;&#xD;
&lt;div style="background-color: #F5F5F5;border: 1px solid #CCCCCC;padding-left:5px;padding-right:5px;" onclick="cnblogs_code_show('77841cd8-6a8b-4ed5-8b67-ec919ad0697d')"&gt;&#xD;
&lt;div id="cnblogs_code_open_77841cd8-6a8b-4ed5-8b67-ec919ad0697d" &gt;&#xD;
&lt;pre&gt;&lt;span style="color: #008080;"&gt; 1&lt;/span&gt; %%%-------------------------------------------------------------------&lt;br /&gt;&lt;span style="color: #008080;"&gt; 2&lt;/span&gt; %%% File : record_util.erl&lt;br /&gt;&lt;span style="color: #008080;"&gt; 3&lt;/span&gt; %%% Author : Gordon Guthrie gordon@hypernumbers.com&lt;br /&gt;&lt;span style="color: #008080;"&gt; 4&lt;/span&gt; %%% Description : utilities for manipulating records&lt;br /&gt;&lt;span style="color: #008080;"&gt; 5&lt;/span&gt; %%%&lt;br /&gt;&lt;span style="color: #008080;"&gt; 6&lt;/span&gt; %%% Created : &lt;span style="color: #800080;"&gt;2&lt;/span&gt; Sep &lt;span style="color: #800080;"&gt;2008&lt;/span&gt; by Gordon Guthrie&lt;br /&gt;&lt;span style="color: #008080;"&gt; 7&lt;/span&gt; %%%-------------------------------------------------------------------&lt;br /&gt;&lt;span style="color: #008080;"&gt; 8&lt;/span&gt; -module(make_ms_util).&lt;br /&gt;&lt;span style="color: #008080;"&gt; 9&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;10&lt;/span&gt; -include(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;myheader.hrl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).&lt;br /&gt;&lt;span style="color: #008080;"&gt;11&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;12&lt;/span&gt; -export([make/&lt;span style="color: #800080;"&gt;0&lt;/span&gt;]).&lt;br /&gt;&lt;span style="color: #008080;"&gt;13&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;14&lt;/span&gt; -define(MODULENAME,&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;ms_util2&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;).&lt;br /&gt;&lt;span style="color: #008080;"&gt;15&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;16&lt;/span&gt; make() -&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;17&lt;/span&gt; {ok,Tree}=&lt;span style="color: #008080;"&gt;epp:&lt;/span&gt;parse_file(&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;myheader.hrl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,[&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;./&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;],[]),&lt;br /&gt;&lt;span style="color: #008080;"&gt;18&lt;/span&gt; Src=make_src(Tree),&lt;br /&gt;&lt;span style="color: #008080;"&gt;19&lt;/span&gt; ok=&lt;span style="color: #008080;"&gt;file:&lt;/span&gt;write_file(?MODULENAME++&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;.erl&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,list_to_binary(Src)).&lt;br /&gt;&lt;span style="color: #008080;"&gt;20&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;21&lt;/span&gt; make_src(Tree) -&amp;gt; make_src(Tree,[]).&lt;br /&gt;&lt;span style="color: #008080;"&gt;22&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;23&lt;/span&gt; make_src([],Acc) -&amp;gt; make_src2(Acc,[],[])&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;24&lt;/span&gt; make_src([{attribute,_,record,Record}|T],Acc) -&amp;gt; make_src(T,[Record|Acc])&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;25&lt;/span&gt; make_src([_H|T],Acc) -&amp;gt; make_src(T,Acc).&lt;br /&gt;&lt;span style="color: #008080;"&gt;26&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;27&lt;/span&gt; make_src2([],Acc1,Acc2) -&amp;gt; top_and_tail(Acc1,Acc2)&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;28&lt;/span&gt; make_src2([H|T],Acc1,Acc2) -&amp;gt; {NewAcc1,NewAcc2}=expand_rec(H),&lt;br /&gt;&lt;span style="color: #008080;"&gt;29&lt;/span&gt; make_src2(T,[NewAcc1|Acc1],[NewAcc2|Acc2]).&lt;br /&gt;&lt;span style="color: #008080;"&gt;30&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;31&lt;/span&gt; expand_rec({Name,Def}) -&amp;gt; expand_fields(Name,Def,&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,[]).&lt;br /&gt;&lt;span style="color: #008080;"&gt;32&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;33&lt;/span&gt; expand_fields(Name,[],N,Acc) -&amp;gt; {mk2(Name,N-&lt;span style="color: #800080;"&gt;1&lt;/span&gt;),&lt;span style="color: #008080;"&gt;lists:&lt;/span&gt;reverse([mk(Name)|Acc])}&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;34&lt;/span&gt; expand_fields(Name,[{record_field,_,{atom,_,F},_}|T],N,Acc) -&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;35&lt;/span&gt; expand_fields(Name,T,N+&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,[mk(Name,F,N)|Acc])&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;36&lt;/span&gt; expand_fields(Name,[{record_field,_,{atom,_,F}}|T],N,Acc) -&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;37&lt;/span&gt; expand_fields(Name,T,N+&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,[mk(Name,F,N)|Acc])&lt;span style="color: #008000;"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;38&lt;/span&gt; expand_fields(Name,[H|T],N,Acc) -&amp;gt; expand_fields(Name,T,N+&lt;span style="color: #800080;"&gt;1&lt;/span&gt;,Acc).&lt;br /&gt;&lt;span style="color: #008080;"&gt;39&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;40&lt;/span&gt; %% mk2/&lt;span style="color: #800080;"&gt;1&lt;/span&gt; builds the no of fields fns&lt;br /&gt;&lt;span style="color: #008080;"&gt;41&lt;/span&gt; mk2(Name,N) -&amp;gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;no_of_fields(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++atom_to_list(Name)++&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;) -&amp;gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++&lt;br /&gt;&lt;span style="color: #008080;"&gt;42&lt;/span&gt; integer_to_list(N)++&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;.&lt;br /&gt;&lt;span style="color: #008080;"&gt;43&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;44&lt;/span&gt; %% mk/&lt;span style="color: #800080;"&gt;1&lt;/span&gt; builds an error line&lt;br /&gt;&lt;span style="color: #008080;"&gt;45&lt;/span&gt; mk(Name) -&amp;gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;get_index(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++atom_to_list(Name)++&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;,F) -&amp;gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++&lt;br /&gt;&lt;span style="color: #008080;"&gt;46&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;exit({error,\&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #008080;"&gt;Record:&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;++atom_to_list(Name)++&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;47&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt; has no field called \&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;++atom_to_list(F)});\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;.&lt;br /&gt;&lt;span style="color: #008080;"&gt;48&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;49&lt;/span&gt; mk(Name,Field,N) -&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;50&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;get_index(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++atom_to_list(Name)++&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;,&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++&lt;br /&gt;&lt;span style="color: #008080;"&gt;51&lt;/span&gt; atom_to_list(Field)++&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;)-&amp;gt; &lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++integer_to_list(N)++&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;.&lt;br /&gt;&lt;span style="color: #008080;"&gt;52&lt;/span&gt; &lt;br /&gt;&lt;span style="color: #008080;"&gt;53&lt;/span&gt; top_and_tail(Acc1,Acc2)-&amp;gt;&lt;br /&gt;&lt;span style="color: #008080;"&gt;54&lt;/span&gt; Top=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;%% This module automatically generated - do not edit\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++&lt;br /&gt;&lt;span style="color: #008080;"&gt;55&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++&lt;br /&gt;&lt;span style="color: #008080;"&gt;56&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;%%% This module provides utilities for use in building\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++&lt;br /&gt;&lt;span style="color: #008080;"&gt;57&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;%%% match specifications from records\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++&lt;br /&gt;&lt;span style="color: #008080;"&gt;58&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++&lt;br /&gt;&lt;span style="color: #008080;"&gt;59&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;-module(&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++?MODULENAME++&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;).\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++&lt;br /&gt;&lt;span style="color: #008080;"&gt;60&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++&lt;br /&gt;&lt;span style="color: #008080;"&gt;61&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;-export([get_index/2,no_of_fields/1]).\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;++&lt;br /&gt;&lt;span style="color: #008080;"&gt;62&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #008080;"&gt;63&lt;/span&gt; Tail1=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;no_of_fields(Other) -&amp;gt; exit({error,\&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;Invalid Record &lt;span style="color: #008080;"&gt;Name:&lt;/span&gt; \&lt;span style="color: #800000;"&gt;""&lt;/span&gt;++&lt;br /&gt;&lt;span style="color: #008080;"&gt;64&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;++Other}).\n\n\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #008080;"&gt;65&lt;/span&gt; Tail2=&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;get_index(Record,_Field) -&amp;gt; exit({error,\""++&lt;br /&gt;&lt;/span&gt;&lt;span style="color: #008080;"&gt;66&lt;/span&gt; &lt;span style="color: #800000;"&gt;"&lt;/span&gt;Invalid Record &lt;span style="color: #008080;"&gt;Name:&lt;/span&gt; \&lt;span style="color: #800000;"&gt;"&lt;/span&gt;&lt;span style="color: #800000;"&gt;++Record}).\n&lt;/span&gt;&lt;span style="color: #800000;"&gt;"&lt;/span&gt;,&lt;br /&gt;&lt;span style="color: #008080;"&gt;67&lt;/span&gt; Top++&lt;span style="color: #008080;"&gt;lists:&lt;/span&gt;flatten(Acc1)++Tail1++&lt;span style="color: #008080;"&gt;lists:&lt;/span&gt;flatten(Acc2)++Tail2.&lt;/pre&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;p&gt;详情点击这里: http://www.trapexit.org/Match_Specifications_And_Records_%28Dynamically%21%29&lt;/p&gt;&#xD;
&lt;p&gt;&lt;br /&gt;一个简单的问题,只要愿意去想,答案不止一个;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&#xD;
&lt;p&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/me-sa/aggbug/2308661.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2011/12/31/erlang0027.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/me-sa/archive/2011/12/28/erlang0026.html</id><title type="text">[Erlang 0026] 目前最优的Erlang IDE - erlIDE</title><summary type="text">作为少数几个还在持续改进的Erlang IDE插件,erlide现在的版本已经堪称是目前最好用的Erlang IDE.</summary><published>2011-12-28T09:19:00Z</published><updated>2011-12-28T09:19:00Z</updated><author><name>坚强2002</name><uri>http://www.cnblogs.com/me-sa/</uri></author><link rel="alternate" href="http://www.cnblogs.com/me-sa/archive/2011/12/28/erlang0026.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/me-sa/archive/2011/12/28/erlang0026.html"/><content type="html">&lt;p&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2011/07/03/erlang0002.html"&gt;&amp;nbsp; &amp;nbsp;[Erlang 0002] Erlang IDE&lt;/a&gt;从我写的一系列Erlang文章阅读人数来看,这篇文章阅读人数最多.可以窥见一斑:好多人在看是否会对一种新语言投入精力的时候,IDE是一个重要的指标,甚至可能就是因为IDE不给力而放弃一种语言,不靠谱是吧,但这是事实;写这篇文章的时候erlide插件还比较差,我提到它的几个问题:&lt;span style="text-decoration: line-through;"&gt;无代码自动完成,偶尔提示一下也特别慢,最关键的一点:&lt;span&gt;&lt;strong&gt;不支持中文&lt;/strong&gt;&lt;/span&gt;,就因为这个无论它多么好直接被否定掉了;&amp;nbsp;&lt;/span&gt;但是作为少数几个还在持续改进的Erlang IDE插件,erlide现在的版本已经堪称是目前最好用的Erlang IDE.&lt;/p&gt;&#xD;
&lt;div&gt;体验了一下,目前的版本:&lt;/div&gt;&#xD;
&lt;ul&gt;&#xD;
&lt;li&gt;&amp;nbsp;完美支持中文,在代码中输入中文会提示你把文件编码更改到UTF-8&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span&gt;&amp;nbsp;已经有了代码自动完成,包括自定义模块的自动完成&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span&gt;&amp;nbsp;方法转到定义功能不错&lt;/span&gt;&lt;/li&gt;&#xD;
&lt;li&gt;&lt;span&gt;&amp;nbsp;打开大文件(约1MB&lt;/span&gt;)没有压力&lt;/li&gt;&#xD;
&lt;li&gt;保存即编译&lt;/li&gt;&#xD;
&lt;/ul&gt;&#xD;
&lt;div&gt;几点注意事项:&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;安装&lt;/strong&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;作为Eclipse插件 首先下载一个&lt;a href="http://www.eclipse.org/downloads/"&gt;Eclipse&amp;nbsp;Classic&lt;/a&gt;最新版本,我下载的是Eclipse Classic 3.7.1,安装完成之后按照,插件主页:&lt;a href="http://erlide.org/"&gt;http://erlide.org/&lt;/a&gt;上的说明即可:&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;Install Erlide by going to Help &amp;rarr; Install new software... . In the dialog, enter http://erlide.org/update as URL. Follow the dialogs with the obvious choices and in the end you will be asked to restart.&lt;br /&gt;&lt;br /&gt; An alternative way to install is from the Eclipse marketplace Help &amp;rarr; Eclipse Marketplace... or if you are using Eclipse 3.7 simply by dragging and dropping the button below into a running Eclipse workspace&amp;nbsp;&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; Restart. Go to Window &amp;rarr; Preferences &amp;rarr; Erlang &amp;rarr; Installed runtimes and add an entry (or several) for your Erlang installation(s) of choice. The required parameters are the name and the path to the top level directory (i.e. $ERL_TOP). Now restart again.&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;strong&gt;版本&lt;/strong&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;你可能担心支持最15B版本的Erlang么?&amp;nbsp;答案:支持,在Eclipse中打开Window &amp;rarr; Preferences &amp;rarr; Erlang,可以选择当前IDE使用哪个版本的Erlang&lt;span&gt;&amp;nbsp;.见下图&lt;/span&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&#xD;
&lt;p&gt;&lt;img src="http://pic002.cnblogs.com/images/2011/17329/2011122817174579.png" alt="" /&gt;&lt;/p&gt;&#xD;
&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span&gt;写的技术文章过时了不郁闷,郁闷的是可以更新自己的博客却更新不了被抓站程序抓走的&lt;/span&gt;&lt;/div&gt;&lt;img src="http://www.cnblogs.com/me-sa/aggbug/2305183.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/me-sa/archive/2011/12/28/erlang0026.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry></feed>
