- 浏览: 39174 次
- 来自: 深圳
文章分类
最新评论
-
ZacMa:
哈哈,突然感觉里面没怎么介绍,全是贴代码了
<8>redis及erl-redis阅读 -
惊涛翻案:
马博士,给我开课吧
<8>redis及erl-redis阅读
1 rr的是使用:erlang中经常会进入debug模式去查找某个ets的信息,一般ets都是由record来定义结构的,但是在debug模块下不方便去查看某个record的定义,这时候可以使用命令rr(ModuleName) 来查看该module中用到的record, 再使用rl(RecordName)就可以查看了
看定义
rr(Module)
Reads record definitions from a module's BEAM file. If there are no record definitions in the BEAM file, the source file is located and read instead. Returns the names of the record definitions read. Module is an atom.
rr(Wildcard)
Reads record definitions from files. Existing definitions of any of the record names read are replaced. Wildcard is a wildcard string as defined in filelib(3) but not an atom.
2 怎么重启一个没有注册的进程,erlang中如果进程没有使用register或者通过gen_server等启动,没有注册,那么该进程只有一个进程id, 在shell中不好重启一个单独的进程,那么使用
PidList = erlang:processes()获取所有进程,再数进程位置n, 再用Pid = list:nth(n, PidLIst). 再调用exit(Pid, Reason).就可以结束了(目前只想到这种笨方法)
(后记:加入进程是<0.57.0>, 那么也可以用pid(0,57,0)来代表进程的pid)
3 关于process_flag(trap_exit, true).
process_flag(trap_exit, Boolean)
When trap_exit is set to true, exit signals arriving to a process are converted to {'EXIT', From, Reason} messages, which can be received as ordinary messages. If trap_exit is set to false, the process exits if it receives an exit signal other than normal and the exit signal is propagated to its linked processes. Application processes should normally not trap exits.
当设置这个参数之后,进程收到的退出的信号会被转化,可以接收,从而可以根据自己的需要来处理,如果不设置会受到相关信号会导致进程退出((normal信号除外))。
当两个有相互连接关系的进程,在退出时候会给彼此发送推出信号;
关于exit(Pid, Reason) -> true
Types:
Pid = pid()
Reason = term()
Sends an exit signal with exit reason Reason to the process Pid.
The following behavior apply if Reason is any term except normal or kill:
If Pid is not trapping exits, Pid itself will exit with exit reason Reason. If Pid is trapping exits, the exit signal is transformed into a message {'EXIT', From, Reason} and delivered to the message queue of Pid. From is the pid of the process which sent the exit signal. See also process_flag/2.
If Reason is the atom normal, Pid will not exit. If it is trapping exits, the exit signal is transformed into a message {'EXIT', From, normal} and delivered to its message queue.
If Reason is the atom kill, that is if exit(Pid, kill) is called, an untrappable exit signal is sent to Pid which will unconditionally exit with exit reason killed.
要注意信号normal和kill, 像进程发送退出信号,当信号为normal时候不会退出(不管是否设置trap_exit),
当信号为kill时候无条件退出(无论进程是否设置trap_exit)
exit(Pid, normal).
exit(Pid, kill).
4 register
使用register(Atom, Pid), 注册进程, unregister(Atom)来取消注册, 使用registered(), 来查看已经注册的名字, whereis(Atom), 来查看进程是否注册,注册就返回Pid, 否则返回 undefined
5 关于spawn
其实spawn和spawn_link 并没有什么奇怪的,但是审spawn的使用却有很多注意点,很可能会影响热更新,因为一个模块在erlang中只允许最多两个版本, 当有存在更多的版本时候,任何前两个版本的进程都会被结束掉, 如果使用spawn(M, F, A), 就会避免这种情况
erlang中重要的进程最好使用gen_server来做,或者用spawn的时候,要注意来监控这个进程,否则,在更新后,会由于把老版本kill掉的原因,时那个进程死掉,我就有一个进程是用来进行数据上报的,是用spawn起的,没有监控,总会莫名的挂掉,现在才发现是上面的原因造成的, 用spawn时候,可以起个进程通过link连接两个进程,然后通过receive来接受消息判断进程是否退出,例如
%% process monitor
on_exit(Pid) ->
spawn(fun () ->
process_flag(trap_exit, true),
link(Pid),
receive
{'EXIT', Pid, Why} ->
?EMSG(["pg2 exit, Reason=", Why]),
NewPid = spawn(?MODULE, loop, []),
[Node | _Ret] = get_other_node(),
on_exit(NewPid),
pg2:join(Node, NewPid)
end
end).
总之使用spawn或者spawn_link,大多情况有三种:
不关心创建进程是否退出: Pid = spawn(fun() -> ... end).
创建进程消失,我也消失,Pid = spawn_link(fun() -> ... end).
第三种,就是上面的exit的例子
6 erlang debug模式的重定向
rp() 之后的结果重定向就可以了
Eshell V5.9 (abort with ^G)
1> lists:seq(1,100).
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,
23,24,25,26,27,28,29|...]
2> {ok, F} = file:open("dump.data", [write]).
{ok,<0.35.0>}
3> group_leader(F, self()).
4> rp(v(1)).
5>
然后就可以看到 dump.data里面的内容就是rp(v(1)), 并且任何内容都可以重定向到文件里面
如果在重定向完成,还想回到原来的shell终端,正常显示,可以这样,
在改变group_leader之前就找到自己的G = group_leader(), 保存原来的group_leader
然后再次改变自己的group_leader,
执行group_leader(M, self()).ok 重新回到了自己的终端
或者直接执行exit(self(), ffff). 退出当前终端,再启动新终端
group_leader的详细解释见
http://www.cnblogs.com/me-sa/archive/2012/02/26/erlang0041.html
当然不用这种重定向也是可以的,利用io:format,看定义,
format(IoDevice, Format, Data) -> ok
IoDevice = device()
device() = atom() | pid()
Either standard_io, standard_error, a registered name, or a pid handling IO protocols (returned from file:open/2).
所以可以用
{ok, P} = file:open("dump.data", [write]).
io:format(P, "~p", [term()]),这样也可以写入文件
7 module_info
在debug模式下经常要手动调用函数,很多函数不知道名字或者是否导出,使用Moudle:module_infoI(), 就可以看到导出了哪些函数可以方便使用,最好不要随便导出不用的函数,如果要调试就加上-compile(export_all).
8 宏 erlang常使用宏
-module(m).
-ifdef(debug).
-define(LOG(X), io:format("{~p,~p}: ~p~n", [?MODULE,?LINE,X])).
-else.
-define(LOG(X), true).
-endif.
编译方法
% erlc -Ddebug m.erl
or
1> c(m, {d, debug}).
{ok,m}
来自http://www.cnblogs.com/me-sa/archive/2011/07/20/erlang0006.html
8 关于容错
erlang中容错的核心思想就是link,就是一个进程监控另一个进程,otp也是这个思想,整个erlang系统也是这个思想,就是用一台机器来监视另外一台机器
监视器 单向监控,monitor
9 erlang两个节点的cookie不同的时候,可以通过set_cookie()来手动设置为相同,而不必重新启动设置
10 add_path
在自己写测试例子的时候经常会用到 不同的目录,加载其他目录的模块, 如果要切换目录有时候是很麻烦的事,
已经在终端上敲了很多命令了,如果所有命令全部再敲一遍当然很浪费时间,使用
code:add_path(Path). 就可以轻松搞定
11 查看一个gen_event中注册了 什么事件
gen_event:which_handlers(error_logger).
12 rebar和宏:
早知道erlang 编译可以用 -Ddebug参数,但是却不知道rebar怎么用, 搜了很多都搜不到,
用英文终于找到了,看来学习一门新语言,不学英语真心不行啊
用rebar编译带宏,只需要这样, 以宏名称为zzz为例
1用 ./rebar -Dzzz compile
2用 加入rebar.config {erl_opts, [{d, zzz}]}.
来自http://stackoverflow.com/questions/6808610/start-erlang-with-user-defined-variable-using-rebar
假设想定义宏 zzz=7可以用
http://riak-users.197444.n3.nabble.com/Rebar-user-defined-macro-td4025906.html
13 通过进程id获得node的名字
本来感觉pg2这个东西用途不大,最近发现这个函数,又感觉pg2的用途来了,多个node的进程全部加入pg2,要往哪个节点发送信息,可通过函数node(Pid) ->Node来获取是哪个节点的,看以下的函数
node(Arg) -> Node
Arg = pid() | port() | reference()
Node = node()
Returns the node where Arg is located. Arg can be a pid, a reference, or a port. If the local node is not alive, nonode@nohost is returned.
Allowed in guard tests.
nodes() -> Nodes
Nodes = [node()]
Returns a list of all visible nodes in the system, excluding the local node. Same as nodes(visible).
nodes(Arg | [Arg]) -> Nodes
Arg = visible | hidden | connected | this | known
Nodes = [node()]
Returns a list of nodes according to argument given. The result returned when the argument is a list, is the list of nodes satisfying the disjunction(s) of the list elements.
Arg can be any of the following:
visible
Nodes connected to this node through normal connections.
hidden
Nodes connected to this node through hidden connections.
connected
All nodes connected to this node.
this
This node.
known
Nodes which are known to this node, i.e., connected, previously connected, etc.
Some equalities: [node()] = nodes(this), nodes(connected) = nodes([visible, hidden]), and nodes() = nodes(visible).
If the local node is not alive, nodes(this) == nodes(known) == [nonode@nohost], for any other Arg the empty list [] is returned.
pg2有个小特性
If a member terminates, it is automatically removed from the group.
14 关于列表解析,
erlang中列表解析用的很频繁 ,看下面的列表,猜猜结果
[Q || [Q, N] <- [[1,1], [2,2], 3], _ <- lists:seq(1, N)].
为什么会是这个结果呢?
结果是[1,2,2]为什么呢,先看下个例子吧
[Q || Q <- [1,2], Q <- [3,4]].
结果是什么呢? 结果是[3,4,3,4],
先看一个learn you some erlang中的一个例子
5> [X+Y || X <- [1,2], Y <- [2,3]].
[3,4,4,5]
This runs the operations 1+2, 1+3, 2+2, 2+3. So if you want to make the list comprehension recipe more generic, you get: NewList = [Expression || GeneratorExp1, GeneratorExp2, ..., GeneratorExpN, Condition1, Condition2, ... ConditionM]. Note that the generator expressions coupled with pattern matching also act as a filter:
列表的一般形式是 [X || Qualifier1, Qualifier2]
Qualifier可以是生成器,也可以使过滤器, 如果是生成器时候,就会像矩阵,一样,来遍历,[Q || Q <- [1,2], Q <- [3,4]]. 中 显然是两个生成器,q的赋值为后者的值(我把它当做逗号运算来看,所以有两个值时候,选择后者),所以,结果就是[3,4,3,4]. 同样的道理使用于第一个例子
15 erlang问题topN,erlangqa上面的
http://erlangqa.com/598/erlang%E6%96%B0%E6%89%8B%E4%B8%8A%E8%B7%AF%E7%96%91%E9%97%AE-top-n?start=0#a_list_title
16 catch的使用
捕获异常的一种方式是使用catch原语, 当捕获一个异常时,这个异常会被转化为错误的一个元组,用法
9> catch (5/4).
1.25
12> catch 6/0.
{'EXIT',{badarith,[{erlang,'/',[6,0],[]},
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,576}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,360}]},
{shell,exprs,7,[{file,"shell.erl"},{line,668}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,623}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,608}]}]}}
local_call(M, F, A) when is_atom(M), is_atom(F), is_list(A) ->
case catch apply(M, F, A) of
{'EXIT',_}=V -> {badrpc, V};
Other -> Other
end.
后者来自rpc.erl;
15 关于group_leader参考:
http://erlangdisplay.iteye.com/blog/336005
17 在tcp接受信息中,经常给某个socket设置inet:setopts(Sock, [{active, once}]);
{ok, Listen} = gen_tcp:connect(..),
{ok, Socket} = gen_tcp:listen(Listen),
loop(Socket).
loop(Socket) ->
receive
{tcp, Socket, Data} ->
....
inet:setopts(Socket, [{active, once}]),
loop(Socket);
{tcp_closed, Socket} ->
....
end.
这样半阻塞,防止消息被客户端淹没
18 登陆远程shell
可以在执行erl 的时候设置cookie, 执行erl -setcookie 'AAAAAAA'
按ctrl+G 可以开启远程shell ,
r NodeName 是开启远程shell
S NodeName 是开启本地shell
19如何找到堆积最长的进程
方法1:lists:foreach( fun(P)-> case erlang:process_info(P, message_queue_len) of {message_queue_len, Count} when Count > 1 -> io:format("~p~p~p ~p~n",[P,erlang:process_info(P, registered_name),erlang:process_info(P, current_function), erlang:process_info(P, message_queue_len)]); _ -> ok end end,erlang:processes()).
方法2,找到堆积最多的top 10
F=fun(Max)-> L=lists:keysort(2,[{{pid,P},erlang:process_info(P,message_queue_len)} ||P<- erlang:processes(),process_info(P,message_queue_len) > {message_queue_len,Max} ]), lists:reverse(lists:nthtail(length(L) - 10, L)) end.
F(10).
20 error浅谈
http://www.erlang.org/doc/reference_manual/errors.html
错误类型一般不会超过这几种,
错误如果是在进程中一般会导致进程的崩溃, 会常常伴有
exception exit: {function_clause, 像这样的语句,如果是单独在eshell中测试不会产生exception exit
一个不错的错误的例子
http://www.trapexit.org/forum/viewtopic.php?p=65767
关于crash report
2.3 Crash Report
Processes started with the proc_lib:spawn or proc_lib:spawn_link functions are wrapped within a catch. A crash report is issued whenever such a process terminates with an unexpected reason, which is any reason other than normal or shutdown. Processes using the gen_server and gen_fsm behaviours are examples of such processes. A crash report contains the following items:
Crasher.
Information about the crashing process is reported, such as initial function call, exit reason, and message queue.
Neighbours.
Information about processes which are linked to the crashing process and do not trap exits. These processes are the neighbours which will terminate because of this process crash. The information gathered is the same as the information for Crasher, shown in the previous item.
http://www.erlang.org/doc/apps/sasl/error_logging.html
21关于try catch
erlang中的任何东西都是表达式,表达式就有值,try end也不例外;
捕获异常有两种方式, 1 种是try catch表达式将一个会抛出异常的函数括号括起来,2是把函数调用包含在catch里面。
erlang里面一般有3种异常, error:R, exit:R, thrown:R, 他们分别对应 erlang:error(Why), exit(Why), thrown(Why)显示的产生一个错误, 如果程序中显式的写
thrown(Wyh)有必要添加注释说明产生异常原因,error(Why)经常用于产生意想不到的系统异常;
原始的捕获异常的方式
try FunOrExpression of
Pattern1 [when Gurd1] -> Expression1;
.......
catch
Exception:ExPattern [when Gurd1] -> ExExpression1;
.....
after
AfterExpression
end
afterExpression是无论如何都会被执行, 执行后表达式本身的值被忽略;
try catch常用几个简化版本:
try F
catch ..
end,
try F of
catch
...
end
出错几率较小的程序:
try my_fun(X)
catch
throw:{thisError, X} -> ...
throw:{someError, X} -> ...
end
my_fun(X) ->
case .... of
....
.... -> throw({thisError, ....})
.....-> throw({thisError, ....})
end
捕获所有的异常:
try Expr
catch
_:_ -> ....
end
或者
try Expr
catch
_ -> ...
end
两个相同的try catch例子
case (catch foo(...))) of
{'EXIT', Why} ->
...
Val ->
...
end
等价于
try foo(...) of
Val -> ....
catch
exit:Why ->
....
end
看定义
rr(Module)
Reads record definitions from a module's BEAM file. If there are no record definitions in the BEAM file, the source file is located and read instead. Returns the names of the record definitions read. Module is an atom.
rr(Wildcard)
Reads record definitions from files. Existing definitions of any of the record names read are replaced. Wildcard is a wildcard string as defined in filelib(3) but not an atom.
2 怎么重启一个没有注册的进程,erlang中如果进程没有使用register或者通过gen_server等启动,没有注册,那么该进程只有一个进程id, 在shell中不好重启一个单独的进程,那么使用
PidList = erlang:processes()获取所有进程,再数进程位置n, 再用Pid = list:nth(n, PidLIst). 再调用exit(Pid, Reason).就可以结束了(目前只想到这种笨方法)
(后记:加入进程是<0.57.0>, 那么也可以用pid(0,57,0)来代表进程的pid)
3 关于process_flag(trap_exit, true).
process_flag(trap_exit, Boolean)
When trap_exit is set to true, exit signals arriving to a process are converted to {'EXIT', From, Reason} messages, which can be received as ordinary messages. If trap_exit is set to false, the process exits if it receives an exit signal other than normal and the exit signal is propagated to its linked processes. Application processes should normally not trap exits.
当设置这个参数之后,进程收到的退出的信号会被转化,可以接收,从而可以根据自己的需要来处理,如果不设置会受到相关信号会导致进程退出((normal信号除外))。
当两个有相互连接关系的进程,在退出时候会给彼此发送推出信号;
关于exit(Pid, Reason) -> true
Types:
Pid = pid()
Reason = term()
Sends an exit signal with exit reason Reason to the process Pid.
The following behavior apply if Reason is any term except normal or kill:
If Pid is not trapping exits, Pid itself will exit with exit reason Reason. If Pid is trapping exits, the exit signal is transformed into a message {'EXIT', From, Reason} and delivered to the message queue of Pid. From is the pid of the process which sent the exit signal. See also process_flag/2.
If Reason is the atom normal, Pid will not exit. If it is trapping exits, the exit signal is transformed into a message {'EXIT', From, normal} and delivered to its message queue.
If Reason is the atom kill, that is if exit(Pid, kill) is called, an untrappable exit signal is sent to Pid which will unconditionally exit with exit reason killed.
要注意信号normal和kill, 像进程发送退出信号,当信号为normal时候不会退出(不管是否设置trap_exit),
当信号为kill时候无条件退出(无论进程是否设置trap_exit)
exit(Pid, normal).
exit(Pid, kill).
4 register
使用register(Atom, Pid), 注册进程, unregister(Atom)来取消注册, 使用registered(), 来查看已经注册的名字, whereis(Atom), 来查看进程是否注册,注册就返回Pid, 否则返回 undefined
5 关于spawn
其实spawn和spawn_link 并没有什么奇怪的,但是审spawn的使用却有很多注意点,很可能会影响热更新,因为一个模块在erlang中只允许最多两个版本, 当有存在更多的版本时候,任何前两个版本的进程都会被结束掉, 如果使用spawn(M, F, A), 就会避免这种情况
erlang中重要的进程最好使用gen_server来做,或者用spawn的时候,要注意来监控这个进程,否则,在更新后,会由于把老版本kill掉的原因,时那个进程死掉,我就有一个进程是用来进行数据上报的,是用spawn起的,没有监控,总会莫名的挂掉,现在才发现是上面的原因造成的, 用spawn时候,可以起个进程通过link连接两个进程,然后通过receive来接受消息判断进程是否退出,例如
%% process monitor
on_exit(Pid) ->
spawn(fun () ->
process_flag(trap_exit, true),
link(Pid),
receive
{'EXIT', Pid, Why} ->
?EMSG(["pg2 exit, Reason=", Why]),
NewPid = spawn(?MODULE, loop, []),
[Node | _Ret] = get_other_node(),
on_exit(NewPid),
pg2:join(Node, NewPid)
end
end).
总之使用spawn或者spawn_link,大多情况有三种:
不关心创建进程是否退出: Pid = spawn(fun() -> ... end).
创建进程消失,我也消失,Pid = spawn_link(fun() -> ... end).
第三种,就是上面的exit的例子
6 erlang debug模式的重定向
rp() 之后的结果重定向就可以了
Eshell V5.9 (abort with ^G)
1> lists:seq(1,100).
[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,
23,24,25,26,27,28,29|...]
2> {ok, F} = file:open("dump.data", [write]).
{ok,<0.35.0>}
3> group_leader(F, self()).
4> rp(v(1)).
5>
然后就可以看到 dump.data里面的内容就是rp(v(1)), 并且任何内容都可以重定向到文件里面
如果在重定向完成,还想回到原来的shell终端,正常显示,可以这样,
在改变group_leader之前就找到自己的G = group_leader(), 保存原来的group_leader
然后再次改变自己的group_leader,
执行group_leader(M, self()).ok 重新回到了自己的终端
或者直接执行exit(self(), ffff). 退出当前终端,再启动新终端
group_leader的详细解释见
http://www.cnblogs.com/me-sa/archive/2012/02/26/erlang0041.html
当然不用这种重定向也是可以的,利用io:format,看定义,
format(IoDevice, Format, Data) -> ok
IoDevice = device()
device() = atom() | pid()
Either standard_io, standard_error, a registered name, or a pid handling IO protocols (returned from file:open/2).
所以可以用
{ok, P} = file:open("dump.data", [write]).
io:format(P, "~p", [term()]),这样也可以写入文件
7 module_info
在debug模式下经常要手动调用函数,很多函数不知道名字或者是否导出,使用Moudle:module_infoI(), 就可以看到导出了哪些函数可以方便使用,最好不要随便导出不用的函数,如果要调试就加上-compile(export_all).
8 宏 erlang常使用宏
-module(m).
-ifdef(debug).
-define(LOG(X), io:format("{~p,~p}: ~p~n", [?MODULE,?LINE,X])).
-else.
-define(LOG(X), true).
-endif.
编译方法
% erlc -Ddebug m.erl
or
1> c(m, {d, debug}).
{ok,m}
来自http://www.cnblogs.com/me-sa/archive/2011/07/20/erlang0006.html
8 关于容错
erlang中容错的核心思想就是link,就是一个进程监控另一个进程,otp也是这个思想,整个erlang系统也是这个思想,就是用一台机器来监视另外一台机器
监视器 单向监控,monitor
9 erlang两个节点的cookie不同的时候,可以通过set_cookie()来手动设置为相同,而不必重新启动设置
10 add_path
在自己写测试例子的时候经常会用到 不同的目录,加载其他目录的模块, 如果要切换目录有时候是很麻烦的事,
已经在终端上敲了很多命令了,如果所有命令全部再敲一遍当然很浪费时间,使用
code:add_path(Path). 就可以轻松搞定
11 查看一个gen_event中注册了 什么事件
gen_event:which_handlers(error_logger).
12 rebar和宏:
早知道erlang 编译可以用 -Ddebug参数,但是却不知道rebar怎么用, 搜了很多都搜不到,
用英文终于找到了,看来学习一门新语言,不学英语真心不行啊
用rebar编译带宏,只需要这样, 以宏名称为zzz为例
1用 ./rebar -Dzzz compile
2用 加入rebar.config {erl_opts, [{d, zzz}]}.
来自http://stackoverflow.com/questions/6808610/start-erlang-with-user-defined-variable-using-rebar
假设想定义宏 zzz=7可以用
http://riak-users.197444.n3.nabble.com/Rebar-user-defined-macro-td4025906.html
13 通过进程id获得node的名字
本来感觉pg2这个东西用途不大,最近发现这个函数,又感觉pg2的用途来了,多个node的进程全部加入pg2,要往哪个节点发送信息,可通过函数node(Pid) ->Node来获取是哪个节点的,看以下的函数
node(Arg) -> Node
Arg = pid() | port() | reference()
Node = node()
Returns the node where Arg is located. Arg can be a pid, a reference, or a port. If the local node is not alive, nonode@nohost is returned.
Allowed in guard tests.
nodes() -> Nodes
Nodes = [node()]
Returns a list of all visible nodes in the system, excluding the local node. Same as nodes(visible).
nodes(Arg | [Arg]) -> Nodes
Arg = visible | hidden | connected | this | known
Nodes = [node()]
Returns a list of nodes according to argument given. The result returned when the argument is a list, is the list of nodes satisfying the disjunction(s) of the list elements.
Arg can be any of the following:
visible
Nodes connected to this node through normal connections.
hidden
Nodes connected to this node through hidden connections.
connected
All nodes connected to this node.
this
This node.
known
Nodes which are known to this node, i.e., connected, previously connected, etc.
Some equalities: [node()] = nodes(this), nodes(connected) = nodes([visible, hidden]), and nodes() = nodes(visible).
If the local node is not alive, nodes(this) == nodes(known) == [nonode@nohost], for any other Arg the empty list [] is returned.
pg2有个小特性
If a member terminates, it is automatically removed from the group.
14 关于列表解析,
erlang中列表解析用的很频繁 ,看下面的列表,猜猜结果
[Q || [Q, N] <- [[1,1], [2,2], 3], _ <- lists:seq(1, N)].
为什么会是这个结果呢?
结果是[1,2,2]为什么呢,先看下个例子吧
[Q || Q <- [1,2], Q <- [3,4]].
结果是什么呢? 结果是[3,4,3,4],
先看一个learn you some erlang中的一个例子
5> [X+Y || X <- [1,2], Y <- [2,3]].
[3,4,4,5]
This runs the operations 1+2, 1+3, 2+2, 2+3. So if you want to make the list comprehension recipe more generic, you get: NewList = [Expression || GeneratorExp1, GeneratorExp2, ..., GeneratorExpN, Condition1, Condition2, ... ConditionM]. Note that the generator expressions coupled with pattern matching also act as a filter:
列表的一般形式是 [X || Qualifier1, Qualifier2]
Qualifier可以是生成器,也可以使过滤器, 如果是生成器时候,就会像矩阵,一样,来遍历,[Q || Q <- [1,2], Q <- [3,4]]. 中 显然是两个生成器,q的赋值为后者的值(我把它当做逗号运算来看,所以有两个值时候,选择后者),所以,结果就是[3,4,3,4]. 同样的道理使用于第一个例子
15 erlang问题topN,erlangqa上面的
http://erlangqa.com/598/erlang%E6%96%B0%E6%89%8B%E4%B8%8A%E8%B7%AF%E7%96%91%E9%97%AE-top-n?start=0#a_list_title
16 catch的使用
捕获异常的一种方式是使用catch原语, 当捕获一个异常时,这个异常会被转化为错误的一个元组,用法
9> catch (5/4).
1.25
12> catch 6/0.
{'EXIT',{badarith,[{erlang,'/',[6,0],[]},
{erl_eval,do_apply,6,[{file,"erl_eval.erl"},{line,576}]},
{erl_eval,expr,5,[{file,"erl_eval.erl"},{line,360}]},
{shell,exprs,7,[{file,"shell.erl"},{line,668}]},
{shell,eval_exprs,7,[{file,"shell.erl"},{line,623}]},
{shell,eval_loop,3,[{file,"shell.erl"},{line,608}]}]}}
local_call(M, F, A) when is_atom(M), is_atom(F), is_list(A) ->
case catch apply(M, F, A) of
{'EXIT',_}=V -> {badrpc, V};
Other -> Other
end.
后者来自rpc.erl;
15 关于group_leader参考:
http://erlangdisplay.iteye.com/blog/336005
17 在tcp接受信息中,经常给某个socket设置inet:setopts(Sock, [{active, once}]);
{ok, Listen} = gen_tcp:connect(..),
{ok, Socket} = gen_tcp:listen(Listen),
loop(Socket).
loop(Socket) ->
receive
{tcp, Socket, Data} ->
....
inet:setopts(Socket, [{active, once}]),
loop(Socket);
{tcp_closed, Socket} ->
....
end.
这样半阻塞,防止消息被客户端淹没
18 登陆远程shell
可以在执行erl 的时候设置cookie, 执行erl -setcookie 'AAAAAAA'
按ctrl+G 可以开启远程shell ,
r NodeName 是开启远程shell
S NodeName 是开启本地shell
19如何找到堆积最长的进程
方法1:lists:foreach( fun(P)-> case erlang:process_info(P, message_queue_len) of {message_queue_len, Count} when Count > 1 -> io:format("~p~p~p ~p~n",[P,erlang:process_info(P, registered_name),erlang:process_info(P, current_function), erlang:process_info(P, message_queue_len)]); _ -> ok end end,erlang:processes()).
方法2,找到堆积最多的top 10
F=fun(Max)-> L=lists:keysort(2,[{{pid,P},erlang:process_info(P,message_queue_len)} ||P<- erlang:processes(),process_info(P,message_queue_len) > {message_queue_len,Max} ]), lists:reverse(lists:nthtail(length(L) - 10, L)) end.
F(10).
20 error浅谈
http://www.erlang.org/doc/reference_manual/errors.html
错误类型一般不会超过这几种,
错误如果是在进程中一般会导致进程的崩溃, 会常常伴有
exception exit: {function_clause, 像这样的语句,如果是单独在eshell中测试不会产生exception exit
一个不错的错误的例子
http://www.trapexit.org/forum/viewtopic.php?p=65767
关于crash report
2.3 Crash Report
Processes started with the proc_lib:spawn or proc_lib:spawn_link functions are wrapped within a catch. A crash report is issued whenever such a process terminates with an unexpected reason, which is any reason other than normal or shutdown. Processes using the gen_server and gen_fsm behaviours are examples of such processes. A crash report contains the following items:
Crasher.
Information about the crashing process is reported, such as initial function call, exit reason, and message queue.
Neighbours.
Information about processes which are linked to the crashing process and do not trap exits. These processes are the neighbours which will terminate because of this process crash. The information gathered is the same as the information for Crasher, shown in the previous item.
http://www.erlang.org/doc/apps/sasl/error_logging.html
21关于try catch
erlang中的任何东西都是表达式,表达式就有值,try end也不例外;
捕获异常有两种方式, 1 种是try catch表达式将一个会抛出异常的函数括号括起来,2是把函数调用包含在catch里面。
erlang里面一般有3种异常, error:R, exit:R, thrown:R, 他们分别对应 erlang:error(Why), exit(Why), thrown(Why)显示的产生一个错误, 如果程序中显式的写
thrown(Wyh)有必要添加注释说明产生异常原因,error(Why)经常用于产生意想不到的系统异常;
原始的捕获异常的方式
try FunOrExpression of
Pattern1 [when Gurd1] -> Expression1;
.......
catch
Exception:ExPattern [when Gurd1] -> ExExpression1;
.....
after
AfterExpression
end
afterExpression是无论如何都会被执行, 执行后表达式本身的值被忽略;
try catch常用几个简化版本:
try F
catch ..
end,
try F of
catch
...
end
出错几率较小的程序:
try my_fun(X)
catch
throw:{thisError, X} -> ...
throw:{someError, X} -> ...
end
my_fun(X) ->
case .... of
....
.... -> throw({thisError, ....})
.....-> throw({thisError, ....})
end
捕获所有的异常:
try Expr
catch
_:_ -> ....
end
或者
try Expr
catch
_ -> ...
end
两个相同的try catch例子
case (catch foo(...))) of
{'EXIT', Why} ->
...
Val ->
...
end
等价于
try foo(...) of
Val -> ....
catch
exit:Why ->
....
end
发表评论
-
erlang版本安装相关问题 <32>
2014-05-10 15:54 629<1> erlang R1603安装后,crytp ... -
关于iolist<30>
2014-01-15 10:42 633iolist是比较常用的数据结构. iolist的 ... -
erlang 字符编码 <29>
2014-01-14 16:31 1266用mochiweb通过网页发送中文到服务器,结果服务器显示乱码 ... -
<27>erlang record
2013-11-19 11:19 780平时总是忘记record的某些使用方法,每次使用都要翻文档, ... -
<26>io:format io_lib:format
2013-11-14 11:07 1320使用io_lib时候要注意参数,尤其是封装json串的时候,否 ... -
<24>用error_logger间隔记录日志
2013-10-22 16:09 657执行下面的代码 test:start(). test.erl ... -
<23>erlang 数据存储
2013-10-15 22:15 1666做为后端开发者,经常 ... -
<22> erlang中的数学计算函数相关
2013-10-10 10:34 16381. 幂函数 match:pow(m,n) 表示m的n次幂 ... -
<20>erlang中的类型和函数说明
2013-09-15 11:25 987erlang是一种动态类型的语言(运行时才决定数据类型),可以 ... -
<19>erlang中的时间,日期
2013-09-06 11:21 1201时间函数涉及的数据类型: DATA TYPES datetim ... -
<18>Efficient guide 之List handling
2013-08-31 18:45 6831 Deep and flat lists lists:fl ... -
<17>Efficiency Guide之Function
2013-08-27 22:30 5841. 函数模式匹配 模式匹配,在函数头,case和receiv ... -
<16>Efficiency Guide之Common Caveats
2013-08-11 11:07 816(1) ++ 如果做一个list的反转,不要这样, naiv ... -
<15> lists模块补充
2013-08-05 20:12 833%% 对list模块经常用到的进行补充 %% 1 对所有元素进 ... -
<15> lists模块解析和补充
2013-07-24 17:57 12%% 对list模块经常用到的进行补充 %% 1 对所有元素 ... -
<12>简述erlang的几种错误
2013-04-14 23:31 11871) badarg Bad argument. The ar ... -
<11>erlang中方便使用的模块和命令(2)
2013-04-06 22:33 807(1) 进程字典到底用不用,很多人推荐使用 http:// ... -
<9>rabbitmq网络层
2013-01-31 00:20 821抽离出了网络层, 逻辑层待以后研究 https://gith ... -
<8>redis及erl-redis阅读
2013-01-16 10:14 8561 redis的功能相当的强大,里面的发布订阅pub/su ... -
<7>pg2 分析
2012-12-08 13:42 1262网上看到erlang的pg2模块似乎没人推荐使用,但是还是有不 ...
相关推荐
标题中的“<27>erlang record”可能指的是Erlang编程语言中的Record特性,它是一种数据结构,类似于结构体或者哈希表,用于组织和操作数据。在Erlang中,Record提供了一种方便的方式来定义和访问具有固定字段的数据...
Quasar 是一个 Java 库,提供了高性能、轻量级的线程,类似 Go 语言的 Channel,Erlang 语言的 Actor 和其他异步编程工具。 In Maven: <dependency> <groupId>co.paralleluniverse</groupId> <artifactId>quasar...
模块系统虽然允许组织代码,但在大型系统中,开发者仍需管理大量代码和模块的交互。这是引入参数化模块的一个动机。 参数化模块的目的是扩展Erlang编程语言,使其能够创建类似于面向对象编程中的回调。参数化模块...
<start>1</start> <end>1000</end> <step>100</step> <time>10s</time> </rate> </load> </config> <scenario name="24-hour stress test"> <session> <!-- 用户行为定义 --> </session> </scenario> </...
1. **嵌入式Erlang代码**:在静态HTML页面中,可以通过`<erl>`标签嵌入Erlang代码,Yaws会解析这些标签并执行对应的`out/1`函数,将结果插入到页面中。这种方式简单且直接,适合轻量级的动态内容生成。 2. **应用...
2. 使用`sudo yum localinstall erlang-23.2.3-1.el7.x86_64.rpm`命令安装Erlang RPM包。 3. 安装过程中可能需要解决依赖关系,确保所有必要的库都已安装。 4. 安装完成后,可以使用`erl`命令来验证Erlang是否成功...
最低要求 快速开始编译项目: make要在/usr/local/bin安装生成的erlang_ls escript: make install命令行参数这些是可以提供给erlang_ls脚本的命令行参数: Usage: Erlang LS [-v] [-t [ < transport> ]] [-p [ < ...
这个文件可能是Java项目中的一个模块,包含RabbitMQ的具体使用示例或者一个简单的队列。分析这个文件可以帮助理解如何在实际项目中集成和利用RabbitMQ进行消息传递。 总结来说,这个压缩包提供了一个完整的RabbitMQ...
4. **使用protobuf生成的Erlang模块**:`pokemon_pb.erl`就是一个例子,它包含了`protobuf`编译器自动生成的函数,用于处理`Pokemon`消息类型的序列化和反序列化。这些函数通常以`encode_msg/1,2`和`decode_msg/2`的...
2. **解压缩tar文件**:使用`tar`命令解压`<PREFIX>.tar.gz`文件到目标目录中。 3. **设置环境变量**:为了使Erlang/OTP能够在系统上运行,可能需要将`<PREFIX>/bin`添加到用户环境变量$PATH中。 4. **验证安装**:...
在 Erlang 中,用户可以使用模块和函数来实现复杂的计算任务。例如,用户可以创建一个模块,定义一个函数来实现某个计算任务,然后在 Erlang Shell 中调用该函数来实现任务。 4. 编译和运行 在 Erlang 中,用户...
模块是Erlang程序的基本单位,包含了特性(attribute)和函数(function)声明。下面将详细介绍Erlang模块的规则、特性、预处理以及相关函数。 4.1 模块规则 Erlang的程序源码被划分为多个模块,每个模块由一系列的...
Usage: emqtt_bench conn [--help < help> ] [-h [ < host> ]] [-p [ < port> ]] [-c [ < count> ]] [-n [ < startnumber> ]] [-i [ < interval> ]] [-u < username> ] [-P < password> ] [-k [ < keepalive
Scalang是消息传递和参与者库,它使Scala和Erlang应用程序可以轻松进行通信。 Scalang包含Erlang分布式节点协议的完整实现。 它提供了一个面向参与者的API ,该API可用于以惯用的,符合OTP的方式与Erlang节点进行...
1. **top 命令**:实时显示系统总体的CPU和内存使用情况,包括各个进程的资源消耗。 2. **htop**:top命令的增强版,提供彩色界面和树状视图,更容易查看进程间的依赖关系。 3. **vmstat**:报告虚拟内存统计信息...
在使用Erlang进行开发时,你可能需要用到以下工具和概念: - **Rebar3**:Erlang的构建和依赖管理工具,帮助你组织项目结构、编译代码和管理依赖。 - **OTP(Open Telephony Platform)**:Erlang的核心库,包含...
如何使用Usage: migerl [-c <config>] [-e [<env>]] [-d [<dir>]] [-t [<title>]] [-a [<all>]] [-v [<version>]] [-h [<help>]] [command ...] -c, --config Config file -e, --env Env name in config ...
骡子郎运输 可以向 Erlang 节点发送消息和从 Erlang 节点接收消息的传输。先决条件必须在要使用此传输的主机上安装 Erlang R13B01 或更高版本。在使用 Erlang 传输之前必须在启动 Erlang 连接器之前运行。 如果你有...
在使用Erlang进行开发时,了解Erlang的REPL(Read-Eval-Print Loop)是很有帮助的,通过erl命令启动,可以快速测试代码和调试问题。Erlang还有强大的模块系统,每个文件对应一个模块,模块内包含函数定义。 OTP库...
Erlang 23引入了一些新特性,例如改进的错误处理、新的模块加载机制和对Unicode的更好支持。RabbitMQ 3.8.17则可能包含了一些安全修复、性能提升和功能增强。 在实际部署中,确保Erlang版本与RabbitMQ版本兼容至关...