学习Erlang的时候在书的留白处随手记录了一些东西,还有一些记录在了demo的注释里面,今天又整理出来了一部分,分享一下.
上一次的地址:[Erlang 0009] Erlang 杂记
- Erlang属于面向消息的语言,面向消息的语言没有共享对象,进程间交互通过收发消息完成
- Erlang中一个已经赋值的变量就是一个指针,指向存储值的存储区
- 单次赋值实际上就是存储区的值不会被修改
- Erlang不共享内存,也就没有了锁的问题
- 函数子句的顺序匹配的顺序是其在文件中的顺序
- 列表解析的数据生成器部分通过模式匹配也可以是达到数据过滤的目的[X||{a,X}<-[{a,1},{b,12},{c,33},{a,23}]].
- lists模块的reverse/1经过高度优化,可以在重排lists元素顺序时考虑使用
Note: instead of writing your ownreverse/1
function, you should uselists:reverse/1
. It's been used so much for tail recursive calls that the maintainers and developers of Erlang decided to turn it into a BIF. Your lists can now benefit from extremely fast reversal (thanks to functions written in C) which will make the reversal disadvantage a lot less obvious. - 所有的BIF都在erlang模块中,所以不要奇怪这个模块包含的函数那么杂
- 由字符序列组成的二进制数据等同于由其每一个字符ASCII编码组成的二进制数据<<"king">> == <<$k,$i,$n,$g>>
- 二进制数据中使用的整数都必须要在0到255之间,这是因为二进制数据包含的每个字节都是8位,2#11111111 <<A>> = <<255>>. <<B>> = <<256>>. <<C>> = <<257>>. A B C 的值分别是255 0 1
- bit语法 End-Sign-Type-Unit 一个数据样例: 8/unsigned-little-integer
- apply(M,F,A)要比直接调用调用对应的方法M:F(A1,A2...)要慢6~10倍,尽量避免使用
- 检查一个模块的元数据可以用 Modlue:module_info().模块编译的时候会自动把module_info创建出来
- beam_lib:chunk/2方法可以在不加载代码的情况下分析beam的元数据
- begin end 块表达式让我想起VB的语法,还真是很少用到,需要写多个表达式的地方基本上都抽取成独立方法了
- F1=fun(X) when X==0 -> X; (X) -> X+100 end. %注意这里的可以使用guard
- step_two(N, Total) when N =/= 0 -> step_two(N-1, Total+N). %注意也是用了guard
- epp erlang预处理器我之前在说宏和record的时候提到过 链接:http://www.cnblogs.com/me-sa/archive/2011/07/20/erlang0006.html
- 进程字典用来放全局只读配置还是很合适的
- erlang:make_ref 创建唯一标识,在gen_tcp常用到
- q() 是init:stop()的别名 erlang:halt() 这两个方法都可以关闭erlang系统
- erl 参数 -s可以有多个依次执行 -noshell参数可以让程序在后台运行
- code:clash()方法在code path中查找重名的模块
- 在shell中按下Ctrl +G 进入"shell JCL" job control language 常用的就是 j c r 三个命令
- 在shell里面执行help() 很多实用的辅助方法
- spawn(fun)这个方法执行不会失败,总会返回一个pid
- erlang:system_info/1可以取到运行时的系统信息,比如进程数 原子数 内存消耗等等
- receive的0超时语句可以帮我们快速清空邮件队列
- 捕捉退出消息的进程被称为系统进程(system process),学习新东西很多时候在于术语带来的门槛
- 在线上处理问题的时候用过exit(Pid,kill)来清理僵尸进程
- 只有在不需要使用DNS服务的场景才可以使用-sname
- 要让Erlang节点在不同主机间互通需要打开TCP和UDP的4369端口,empd(Erlang Port Mapper Daemon)会使用这个端口
- 使用分布式Erlang需要打开一些端口或指定端口范围,并确保防火墙已经放开 启动参数使用-kernel inet_dist_listen_min
- file:consult可以直接把文件中的Erlang项读取出来 file:unconsult可以把Erlang项写入文件
- io:format("123~w~n",["abc"]). 输出:123[97,98,99] ~w以标准语法写入数据
- io:format("123~p~n",["abc"]). 输出:123“abc” ~p 完整打印参数
- group_leader()的作用就是管理输出,比如rpc调用会把目标机执行的结果输出截获输出到当前shell
- A Compacting Garbage Collector for ERLANG (1997) http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.2421
-
%%统一的调用接口 捕获异常执行M F Ainit_p_do_apply(M, F, A) ->tryapply(M, F, A)catchClass:Reason ->exit_p(Class, Reason)end.
- %%通过注册名寻找进程Pid
name_to_pid(Name) ->
case whereis(Name) of
undefined ->
case global:safe_whereis_name(Name) of
undefined ->
exit(could_not_find_registerd_name);
Pid ->
Pid
end;
Pid ->
Pid
end. -
erlang:get_stacktrace().Normally, the execution stack trace isn’t included in the part of the exceptionthat you can see; it’s stored internally. You can inspect the stack trace of thelatest thrown exception of the current process by calling the built-in functionerlang:get_stacktrace().
-
%%检查进程是否存活is_process_alive(Pid)when is_pid(Pid) ->rpc:call(node(Pid), erlang, is_process_alive, [Pid]).
- erlang:system_info(min_heap_size).
{min_heap_size,233}
erlang:system_info(min_bin_vheap_size).
{min_bin_vheap_size,46368}
erlang:system_info(fullsweep_after).
{fullsweep_after,65535} - erl -detached参数来脱离对终端的依赖
- Erang Performance Tuning 来自ejabberd项目http://www.ejabberd.im/tuning
-
Note: Tail recursion as seen here is not making the memory grow because when the virtual machine sees a function calling itself in a tail position (the last expression to be evaluated in a function), it eliminates the current stack frame. This is called tail-call optimisation (TCO) and it is a special case of a more general optimisation named Last Call Optimisation (LCO).
LCO is done whenever the last expression to be evaluated in a function body is another function call. When that happens, as with TCO, the Erlang VM avoids storing the stack frame. As such tail recursion is also possible between multiple functions. As an example, the chain of functions
a() -> b(). b() -> c(). c() -> a().
will effectively create an infinite loop that won't go out of memory as LCO avoids overflowing the stack. This principle, combined with our use of accumulators is what makes tail recursion useful. -
Note: The correct ordering of each element in a comparison is the following:
number < atom < reference < fun < port < pid < tuple < list < bit string
You don't know all these types of things yet, but you will get to know them through the book. Just remember that this is why you can compare anything with anything! To quote Joe Armstrong, one of the creators of Erlang: "The actual order is not important - but that a total ordering is well defined is important."