Erlang常用代码段

  • 十六进制字符串转为二进制

    hex_to_bin(Bin) ->  
    	hex2bin(Bin).
    	
    hex2bin(Bin) when is_binary(Bin) ->
    	hex2bin(binary_to_list(Bin));
    hex2bin([]) ->
    	<<>>;
    hex2bin([X, Y | Rest]) ->
    	<<(erlang:list_to_integer([X], 16) * 16 + erlang:list_to_integer([Y], 16)):8, (hex2bin(Rest))/binary>>.
    
  • 二进制转为十六进制字符串

    bin2hex(B) ->
    	bin2hex(B, lower).
    	
    bin2hex(B, LowerOrUpper) when is_binary(B) ->
    	bin2hex(binary_to_list(B), LowerOrUpper);
    bin2hex(L, upper) ->
    	LH0 = lists:map(fun(X) -> erlang:integer_to_list(X, 16) end, L),
    	LH = lists:map(fun([X, Y]) -> [X, Y]; ([X]) -> [$0, X] end, LH0),
    	lists:flatten(LH);
    bin2hex(B, lower) ->
    	H = bin2hex(B, upper),
    	string:to_lower(H).
    
  • 反编译代码
    有时候线上出问题的时候,需要查看线上运行的代码,这时候就用到反编译了。

decompile(Mod) ->
    {ok, {_, [{abstract_code, {_, AC}}]}} = beam_lib:chunks(code:which(Mod), [abstract_code]),
    try
        io:format("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))])
    catch
        io:format("~ts~n", [erl_prettypr:format(erl_syntax:form_list(AC))])
    end.
  • 分裂进程
    erlang分裂进程的函数是erlang:spawn。选项有

    spawn(Fun) -> pid()
    spawn(Node, Fun) -> pid() %如果Node不存在,返回一个无用的pid
    spawn(Module, Function, Args) -> pid()
    spawn(Node, Module, Function, Args) -> pid()
    spawn_link(Fun) -> pid()
    spawn_link(Node, Fun) -> pid()
    spawn_link(Module, Function, Args) -> pid()
    spawn_link(Node, Module, Function, Args) -> pid()
    spawn_monitor(Fun) -> {pid(), reference()}
    spawn_monitor(Module, Function, Args) -> {pid(), reference()}
    spawn_opt(Fun, Options) -> pid() | {pid(), reference()}
    spawn_opt(Node, Fun, Options) -> pid() | {pid(), reference()}
    spawn_opt(Module, Function, Args, Options) -> pid() | {pid(), reference()}
    spawn_opt(Node, Module, Function, Args, Options) -> pid() | {pid(), reference()}
    Options = [Option]
    Option = 
        link |
        monitor | 
        {priority, Level :: priority_level()} |
        {fullsweep_after, Number :: integer() >= 0} |
        {min_heap_size, Size :: integer() >= 0} |
        {min_bin_vheap_size, VSize :: integer() >= 0}
        priority_level() = low | normal | high | max
    
    + link: 父进程与子进程建立连接
    + monitor: 父进程监控子进程
    + {priority, Level}: 设置新的进程的优先级。等价于在新进程中执行process_flag(priority, Level)。区别在于,spawn的时候设置优先级,优先级会在进程被选择运行之前就设置好了。
    + {fullsweep_after, Number}:只是用在调整性能上。Erlang的运行系统,使用的是分代的垃圾回收机制。用一个『old heap』保存至少存活了一个垃圾回收周期的数据,当old heap空间不够时,就会执行垃圾回收。
    + {min_heap_size, Size},只是用在调整性能上。设置heap的最小size,单位是word。将这个值设置的比系统默认的大的话,会加速一些进程运行,因为会减少垃圾回收的执行次数。但是太大会导致内存不够,减慢系统运行。
    + {min_bin_vheap_size, VSize},只是用在调整性能上。

+ 交叉引用工具:xref。xref通过分析函数的调用和定义,发现函数、模块、应用和版本之间的依赖关系。这个工具可以帮助查看是否有函数名输入错误。在用rebar打包时,可以用rebar xref执行。 
  
+ 获得ps命令得到的消耗的内存  

    ```erlang
    get_ps_real_memory() ->
        Cmd = "pid=`echo $$`;p=`ps -ef | awk -v pid=$pid '$2 == pid {print $3}'`;mem=`ps -o rss -p $p | grep -v RSS`;r=$(($mem/1024));echo $r",
        os:cmd(Cmd),
        Result = os:cmd(Cmd),
        string:substr(Result, 1, length(Result) - 1).
    ```    

+ 获得top命令得到的消耗的内存  

    ```erlang
    get_top_real_memory() ->
        Cmd = "pid=`echo $$`;p=`ps -ef | awk -v pid=$pid '$2 == pid {print $3}'`;mem=`cat /proc/$p/stat | awk '{print $24}'`;r=$(($mem*4096/1024/1024));echo $r",
        Result = os:cmd(Cmd),
        case length(Result) > 1 of
            true ->
                string:substr(Result, 1, length(Result) -1);
            false ->
                0
        end.
    ```  

+ 获得当前cpu的核数   

    ```erlang
    get_cpu_count() ->
        Cmd = "cat /proc/cpuinfo | grep processor | wc -l",
        R = os:cmd(Cmd),
        case string:to_integer(R) of
            {Count, _} when is_integer(Count) -> Count;
            {error, _} -> 0
        end.
    ```  
+ 获得ps命令得到的虚拟内存消耗  

    ```erlang
    get_ps_virtual_memory() ->
        Cmd = "pid=`echo $$`;p=`ps -ef | awk -v pid=$pid '$2 == pid {print $3}'`;mem=`ps -o vsz -p $p | grep -v VSZ`;r=$(($mem/1024));echo $r",
        Result = os:cmd(Cmd),
        string:substr(Result, 1, length(Result) - 1).
    ```

+获得top命令得到的虚拟内存消耗

    ```erlang
    get_top_virtual_memory() ->
        Cmd = "pid=`echo $$`;p=`ps -ef | awk -v pid=$pid '$2 == pid {print $3}'`;mem=`cat /proc/$p/stat | awk '{print $24}'`;r=$(($mem*4096/1024/1024));echo $r",
        Result = os:cmd(Cmd),
        case length(Result) > 1 of
            true ->
                string:substr(Result, 1, length(Result) - 1);
            false ->
                0
        end.
    ```
    
+ 获得erlang运行时的进程信息

```erlang
process_infos() ->          
    filelib:ensure_dir("./log/"),
    File = "./log/processes_infos.log",
    {ok, Fd} = file:open(File, [write, raw, binary, append]), 
    Fun = fun(Pi) ->
                   Info = io_lib:format("=>~p \n\n",[Pi]),
                  case  filelib:is_file(File) of
                        true   ->   file:write(Fd, Info);
                        false  ->
                            file:close(Fd),
                            {ok, NewFd} = file:open(File, [write, raw, binary, append]),
                            file:write(NewFd, Info)
                     end,
                     timer:sleep(20)
                 end,
    [Fun(erlang:process_info(P)) ||   P <- erlang:processes()]. 
  • eralng gen_server:call

这是一个同步调用,pid1通过erlang:send()发送给pid2消息后,receive等待返回,这时候pid1处于阻塞状态。pid2是一个gen_server行为模式的进程,loop函数接收到消息后,进行相应处理,并返回。

  • gen_server:cast

直接用erlang:send发送'$gen_cast'消息。

posted @ 2016-06-29 11:14  我的娃会叫爸爸啦  阅读(1017)  评论(0编辑  收藏  举报