erlang编程的小技巧 (持续更新中...)

这个文章用于记录我遇到的erlang编码中的技巧。

1.
%% http://lukego.livejournal.com/6753.html - that doesn't care about
%% the order in which results are received.
upmap(F, L) ->
Parent = self(),
Ref = make_ref(),
[[color=red]receive {Ref, Result} -> Result end[/color]
|| _ <- [spawn(fun() -> Parent ! {Ref, F(X)} end) || X <- L]].

2.
http://www.erlang.org/ml-archive/erlang-questions/200301/msg00053.html
Good day,

I've surprisingly found Y-combinator very useful to solve practical
problem of writing recursive anonymous functions in Erlang.

Code were translated to Erlang from
http://www.ece.uc.edu/~franco/C511/html/Scheme/ycomb.html.


-module(lambda).

-export([y/1, mk_fact/0]).

%% Y-combinator itself
y(X) ->
F = fun (P) -> X(fun (Arg) -> (P(P))(Arg) end) end,
F(F).

%% Factorial example
mk_fact() ->
F =
fun (FA) ->
fun (N) ->
if (N == 0) -> 1;
true -> N * [color=red]FA(N-1)[/color]
end
end
end,
y(F).


>From shell:

1> F = mk_fact().
#Fun<lambda.3.115879927>

2> F(5).
120

Best Regards,
Vladimir Sekissov

3.

1> string:concat("hello ", "world").
"hello world"
2> Module = list_to_atom("string").
string
3> Func = list_to_atom("concat").
concat
4> Module:Func("like", "this").
"likethis"


4.
prim模块IO操作与有同步和异步的版本。 但是inet_driver的实现全部是异步的的, 原因是内部使用反应器。


5. vanilla_driver最高效的读文件行的方法
1> erlang:open_port("hello.txt", [stream,line, in,eof]).
#Port<0.480>
2> flush().
Shell got {#Port<0.447>,{data,{eol,"hello"}}}
Shell got {#Port<0.447>,{data,{eol,"world"}}}
Shell got {#Port<0.447>,eof}
ok

6. Break模式下 'o' 查看port消息 未公开

7.
erts_debug:get_internal_state(node_and_dist_references).
/*
Returns an erlang term on this format:

{{node_references,
[{{Node, Creation}, Refc,
[{{ReferrerType, ID},
[{ReferenceType,References},
'...']},
'...']},
'...']},
{dist_references,
[{Node, Refc,
[{{ReferrerType, ID},
[{ReferenceType,References},
'...']},
'...']},
'...']}}
*/

8.
/*
* The "node_tables module" contain two (hash) tables: the node_table
* and the dist_table.
*
* The elements of the node_table represents a specific incarnation of
* an Erlang node and has {Nodename, Creation} pairs as keys. Elements
* in the node_table are referred to from node containers (see
* node_container_utils.h).
*
* The elements of the dist_table represents a (potential) connection
* to an Erlang node and has Nodename as key. Elements in the
* dist_table are either referred to from elements in the node_table
* or from the process or port structure of the entity controlling
* the connection.
*
* Both tables are garbage collected by reference counting.
*/

9.
%%%-----------------------------------------------------------------
%%% The process structure in kernel is as shown in the figure.
%%%
%%% ---------------
%%% | kernel_sup (A)|
%%% ---------------
%%% |
%%% -------------------------------
%%% | | |
%%% <std services> ------------- -------------
%%% (file,code, | erl_dist (A)| | safe_sup (1)|
%%% rpc, ...) ------------- -------------
%%% | |
%%% (net_kernel, (disk_log, pg2,
%%% auth, ...) ...)
%%%
%%% The rectangular boxes are supervisors. All supervisors except
%%% for kernel_safe_sup terminates the enitre erlang node if any of
%%% their children dies. Any child that can't be restarted in case
%%% of failure must be placed under one of these supervisors. Any
%%% other child must be placed under safe_sup. These children may
%%% be restarted. Be aware that if a child is restarted the old state
%%% and all data will be lost.

10。 shell内置命令rp用于看格式化的数据。 比如rp(processes()).

11. OTP-6850: Literal lists, tuples, and binaries are no longer constructed at run-time as they used to be, but are stored in a per-module constant pool. Literals that are used more than once are stored only once.

12. lc可以这样用。
Eshell V5.5.3.1 (abort with ^G)
1> Nums = [1,2,3], Nouns = [shoe,box,tape], Verbs = [].
[]
2> [Nums || Nums =/= []] ++ [Nouns || Nouns =/= []] ++ [Verbs || Verbs
=/= []].
[[1,2,3],[shoe,box,tape]]


13.
node_port(Node)->
{_, Owner}=lists:keyfind(owner, 1, element(2, net_kernel:node_info(Node))),
hd([P|| P<-erlang:ports(), erlang:port_info(P, connected) == {connected,Owner}])

14.
inet:setopts(node_port('xx@nd-desktop'), [{high_watermark, 131072}]).


15.
erl -kernel inet_default_connect_options '[{sndbuf, 1048576}, {high_watermark, 131072}]'

16. ICC 编译选项

export \
CC=icc \
CXX=icpc \
CFLAGS=" -O3 -ip -static -static-intel -no-gcc -no-prec-div -mp -unroll2 -xT" \
CXXFLAGS="-O3 -ip -static -static-intel -no-gcc -no-prec-div -mp -unroll2 -xT" \
LDFLAGS='-static -static-intel' \
LD=xild \
AR=xiar


17.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Load regulator
%%
%% This is a poor mans substitute for a fair scheduler algorithm
%% in the Erlang emulator. The mnesia_dumper process performs many
%% costly BIF invokations and must pay for this. But since the
%% Emulator does not handle this properly we must compensate for
%% this with some form of load regulation of ourselves in order to
%% not steal all computation power in the Erlang Emulator ans make
%% other processes starve. Hopefully this is a temporary solution.


18.
The magic commands in the shell. The full list is in the manual, but the ones I use most are:
* f() - forget all variables
* f(X) - forget X
* v(42) - recall result from line 42
* v(-1) - recall result from previous line
* rr(foo) - read record definitions from module foo


19.
beam_lib:chunks can get source code from a beam that was compiled with debug on which can be really usefull
{ok,{_,[{abstract_code,{_,AC}}]}} = beam_lib:chunks(Beam,[abstract_code]).
io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(AC))]).

20.
ets:fun2ms(fun({Foo, _, Bar}) when Foo > 0 -> {Foo, Bar} end).
[{{'$1','_','$2'},[{'>','$1',0}],[{{'$1','$2'}}]}]

21.
# erl
Erlang R13B01 (erts-5.7.2) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.7.2 (abort with ^G)
1> H = fun ({trace, _, exit,S},_)-> io:format("got bad arg~p",[S]); (_,_)->skip end.
#Fun<erl_eval.12.113037538>
2> dbg:tracer(process, {H,null}).
{ok,<0.36.0>}
3> dbg:p(new, [procs]).
{ok,[{matched,nonode@nohost,0}]}
4>
4> spawn(fun() -> abs(x) end).
got bad arg{ok,[{call,2,
{atom,2,spawn},
[{'fun',2,
{clauses,
[{clause,2,[],[],
[{call,2,{atom,2,abs},[{atom,2,x}]}]}]}}]}],
3}got bad arg{badarg,[{erlang,abs,[x]}]}
=ERROR REPORT==== 13-Aug-2009::16:38:56 ===
Error in process <0.40.0> with exit value: {badarg,[{erlang,abs,[x]}]}

<0.40.0>

22;

The condition is specified by the user as a module name CModule and a function name CFunction. When a process reaches the breakpoint, CModule:CFunction(Bindings) will be evaluated. If and only if this function call returns true, the process will stop. If the function call returns false, the breakpoint will be silently ignored.

Bindings is a list of variable bindings. Use the function int:get_binding(Variable,Bindings) to retrieve the value of Variable (given as an atom). The function returns unbound or {value,Value}.

22.

export ERL_TOP=/usr/lib/erlang/

dialyzer --build_plt --output_plt $HOME/.dialyzer_otp.plt -r $ERL_TOP/lib/stdlib/ebin
$ERL_TOP/lib/kernel/ebin $ERL_TOP/lib/mnesia/ebin $ERL_TOP/lib/ssl/ebin
$ERL_TOP/lib/asn1/ebin $ERL_TOP/lib/compiler/ebin $ERL_TOP/lib/crypto/ebin
$ERL_TOP/lib/syntax_tools/ebin $ERL_TOP/lib/inets/ebin $ERL_TOP/lib/sasl/ebin
$ERL_TOP/lib/odbc/ebin

23. 查看系统的上下文切换
k# cat csw.stp
#!/usr/local/bin/stap -k

global lasttime, times, execnames, switches, csw

probe kernel.function("context_switch") {
#probe scheduler.cpu_off{
switches ++ # count number of context switches
now = get_cycles()
times[pid()] += now-lasttime # accumulate cycles spent in process
execnames[pid()] = execname() # remember name of pid
csw[pid()]++
lasttime = now
}

probe timer.ms(3000) {

printf ("\n%10s %30s %20s %20s (%d switches)\n",
"pid", "execname", "cycles", "csw", switches);

foreach ([pid] in times-) # sort in decreasing order of cycle-count
printf ("%10d %30s %20d %20d\n", pid, execnames[pid], times[pid], csw[pid]);

# clear data for next report
delete times
delete execnames
delete csw

switches = 0

}

probe begin {
lasttime = get_cycles()
}

24.
root@nd-desktop:~/test/arksea# cat test.erl
-module(test).

-export([start/0]).

start()->
{ok, Sock} = gen_tcp:listen(0, []),
{ok, Handle} = inet:getfd(Sock),
Command = "erl -noshell -s child -handle " ++ integer_to_list(Handle),
Child = case (catch open_port({spawn, Command}, [in, {line, 256}])) of
{'EXIT', Reason}->
io:format("open child error, reason ~p~n", [Reason]),
halt(1);
Port-> Port
end,

register(?MODULE, self()),
loop(Child).

loop(Child)->
receive
{Child, {data, Result}} ->
io:format("child say ~p~n", [Result]),
loop(Child);
stop->
halt(0)
end.


root@nd-desktop:~/test/arksea# cat child.erl
-module(child).
-export([start/0]).

start()->
{ok, [[HandleArg|_]|_]} = init:get_argument(handle),
Handle = list_to_integer(HandleArg),
io:format("handle: ~w~n", [Handle]),
{ok,Socket} = gen_tcp:fdopen(Handle, []),
io:format("socket: ~p~n", [Socket]),
halt(0).

25. Regarding the GC, consider what it has to work with. You are
building a very large data structure in a tight loop. The
process will continuously run out of heap, triggering the GC.
The GC will copy live data (which is going to be most of it)
to another copy of the heap. If that's not enough, it will
run a fullsweep, also looking at data that survived the
previous GC (no garbage there, since the list just keeps
growing). This creates yet another heap copy.
Finally, it does a resize of the heap, if necessary.


26. 反编译
f(),{ok, {_, [{abstract_code, {_,Abs}}]}} = beam_lib:chunks("xxx.beam", [abstract_code]), io:fwrite("~s~n", [erl_prettypr:format(erl_syntax:form_list(Abs))]).

27.
打印 usage
erl +
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值