[Erlang 0077] Erlang 雜記 V



[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. 

 

[6] Copying data can be expensive for large structures and can cause higher memory  usage  if  the  sender  also  needs  to  keep  their  copy  of  the  data.  In  practice,  this means you must be aware of and manage the size and complexity of messages you’re sending.  But  in  normal,  idiomatic  Erlang  programs,  the  majority  of  messages  are small, and the overhead of copying is usually negligible.
 
[7]A typical thread in a modern operating system reserves some megabytes of address space  for  its  stack  (which  means  a  32-bit  machine  can  never  have  more  than  a  few thousand simultaneous threads), and it still crashes if it uses more stack space than expected. Erlang processes, on the other hand, start with only a couple of hundred bytes of stack space each, and they grow or shrink automatically as required.
 
[8]OTP framework provides just about everything you need: both a methodology for structuring applications using supervision, and stable, battle-hardened libraries to build them on.
 
[9] At  the  lowest  levels  of  the  system, Erlang does all I/O in an event-based way, which lets a program handle each chunk of data as it enters or leaves the system in a nonblocking manner. This reduces the need to set up and tear down connections, and it removes the need for OS-based locking and context switching.
 
[10] 對於代碼中的常量在HIPE的時候會編譯優化放在池中,比如下面的代碼就不會反復創建常量字符串

 

para(Text) ->

   ["<p class=\"normal\">", Text, "</p>"]. 

http://prog21.dadgum.com/10.html

 

[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

 

代碼片段:

 

View Code
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"

  

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM