[1] Erlang 语言设计的目标是并发,支持并发的核心机制是进程 "Making reliable distributed systems in the presence of sodware errors" [PDF]
[2] 并发是一种不按照顺序执行的能力,并行是从处理执行的角度"是否可以同时做";还有一种角度:并发是逻辑上的同时发生(simultaneous),并行是物理上的同时发生.
[3]其实无论是面向过程还是面向对象,各种编程范式都是对现实世界中的一种抽象 ,只不过关注的点不同
[4]Shared memory could reasonably be called the GOTO of our time: it’s the current mainstream technique for process communication; it has been so for a long, long time; and just like programming with GOTO, there are numerous ways to shoot yourself in the foot.
[5] In Erlang, the message passing primitives are asynchronous, because it’s easy to implement the synchronous form when necessary by making the receiver always send an explicit reply that the sender can wait for.
para(Text) ->
["<p class=\"normal\">", Text, "</p>"].
[11] hipe_bifs:bitarray 提供了类似Redis命令中setbit getbit的作用 @yufeng的介绍
Eshell V5.9 (abort with ^G) 1> hipe_bifs:bitarray(10,false). <<0,0>> 2> hipe_bifs:bitarray_update(v(1), 3, true). <<8,0>> 3> hipe_bifs:bitarray_update(v(2), 7, true). <<136,0>> 4> hipe_bifs:bitarray_update(v(3), 1, true). <<138,0>> 5> hipe_bifs:bitarray_sub(v(4), 1). true 6> hipe_bifs:bitarray_sub(v(4), 2). false 7> hipe_bifs:bitarray_sub(v(4), 3). true 8> hipe_bifs:bitarray_sub(v(4), 4). false 9> hipe_bifs:bitarray_sub(v(4), 7). true 10>
[12] The external term format is mainly used in the distribution mechanism of Erlang.
http://www.erlang.org/doc/apps/erts/erl_ext_dist.html 看下面的测试代码
Eshell V5.9 (abort with ^G) (node_b@192.168.10.160)1> net_adm:ping('node_a@192.168.10.160'). pong (node_b@192.168.10.160)2> {a_shell,'node_a@192.168.10.160'}!hello_world. hello_world (node_b@192.168.10.160)3> {a_shell,'node_a@192.168.10.160'}!self(). <0.38.0> (node_b@192.168.10.160)4>
Eshell V5.9 (abort with ^G) (node_a@192.168.10.160)1> register(a_shell,self()). true (node_a@192.168.10.160)2> flush(). Shell got hello_world ok (node_a@192.168.10.160)3> flush(). Shell got <5911.38.0> ok (node_a@192.168.10.160)4> node(pid(5911,38,0)). 'node_b@192.168.10.160' (node_a@192.168.10.160)5>
[13] 为什么shell进程重启了,原来的变量还在
可以看一下 erl5.9.1\lib\stdlib-1.18.1\src\shell.erl的代码 ,shell进程遇到异常之后的处理逻辑 包含变量绑定的重建shell_rep(Ev, Bs0, RT, Ds0) 方法
Eshell V5.9.1 (abort with ^G) 1> self(). <0.30.0> 2> B=23. 23 3> 1/0. ** exception error: bad argument in an arithmetic expression in operator '/'/2 called as 1 / 0 4> self(). <0.34.0> 5> B. 23 6> b(). B = 23 ok
代码片段:
shell_rep(Ev, Bs0, RT, Ds0) -> receive {shell_rep,Ev,{value,V,Bs,Ds}} -> {V,Ev,Bs,Ds}; {shell_rep,Ev,{command_error,{Line,M,Error}}} -> fwrite_severity(benign, <<"~w: ~s">>, [Line, M:format_error(Error)]), {{'EXIT',Error},Ev,Bs0,Ds0}; {shell_req,Ev,get_cmd} -> Ev ! {shell_rep,self(),get()}, shell_rep(Ev, Bs0, RT, Ds0); {shell_req,Ev,exit} -> Ev ! {shell_rep,self(),exit}, exit(normal); {shell_req,Ev,{update_dict,Ds}} -> % Update dictionary Ev ! {shell_rep,self(),ok}, shell_rep(Ev, Bs0, RT, Ds); {ev_exit,{Ev,Class,Reason0}} -> % It has exited unnaturally receive {'EXIT',Ev,normal} -> ok end, report_exception(Class, Reason0, RT), Reason = nocatch(Class, Reason0), {{'EXIT',Reason},start_eval(Bs0, RT, Ds0), Bs0, Ds0}; {ev_caught,{Ev,Class,Reason0}} -> % catch_exception is in effect report_exception(Class, benign, Reason0, RT), Reason = nocatch(Class, Reason0), {{'EXIT',Reason},Ev,Bs0,Ds0}; {'EXIT',_Id,interrupt} -> % Someone interrupted us exit(Ev, kill), shell_rep(Ev, Bs0, RT, Ds0); {'EXIT',Ev,{Reason,Stacktrace}} -> report_exception(exit, {Reason,Stacktrace}, RT), {{'EXIT',Reason},start_eval(Bs0, RT, Ds0), Bs0, Ds0}; {'EXIT',Ev,Reason} -> report_exception(exit, {Reason,[]}, RT), {{'EXIT',Reason},start_eval(Bs0, RT, Ds0), Bs0, Ds0}; {'EXIT',_Id,R} -> exit(Ev, R), exit(R); _Other -> % Ignore everything else shell_rep(Ev, Bs0, RT, Ds0) end.
[14] %模块已经加载而且具有指定的方法导出, 注意最后一个参数是Arity 代表几目运算
erlang:function_exported(Module, Function, Arity) -> bool()
Types:
Module = Function = atom()
Arity = int()
Returns true if the module Module is loaded and contains an exported function Function/Arity; otherwise
false.
Returns false for any BIF (functions implemented in C rather than in Erlang).
15.
IP地址转换 1> inet_parse:address("127.0.0.1"). {ok,{127,0,0,1}} 2> inet_parse:address("::1"). {ok,{0,0,0,0,0,0,0,1}} 3> inet_parse:address("300.400.500.600"). {error,einval} And here is Erlang tuple to string conversion: 1> inet_parse:ntoa({127,0,0,1}). "127.0.0.1" 2> inet_parse:ntoa({0,0,0,0,0,0,0,1}). "::1"