显示标签为“erlang”的博文。显示所有博文
显示标签为“erlang”的博文。显示所有博文

2010年5月26日星期三

unix erlang man 安装

在Unix系统,man手册页并不是默认安装的,如果命令 erl -man ... 没有工 作,你需要自己安装man手册页。所有的man手册页都是单独压缩存档的, 可以到 http://www.erlang.org/download.html 下载。man手册页可以通过 root解压并安装到Erlang的安装目录,通常为 。
/usr/local/lib/e

2010年5月24日星期一

webtool 远程访问启动方式

webtool:start("/usr/local/lib/erlang/lib/webtool-0.8.4/priv", [{port, 8889}, {bind_address, {0,0,0,0}}, {server_name, "testtest.com"}]).

2010年5月21日星期五

修改 computer name

系统偏好设置->共享,修改“电脑名称”,就可以了。

另外,楼主说的在终端命令行提示符里的东东不是HostName,是ComputerName。用楼上同学说的scutil也可以修改,具体命令是:
sudo scutil --set ComputerName


修改 computer name 后要修改 hosts, 127.0.0.1

2010年5月20日星期四

mochiweb 不一定每个请求是一个新的process(转)

转:http://approach.javaeye.com/blog/547638

今天试了一下mochiweb,这个东东的文档实在是少的可怜,推荐一个不错的tutorial:

http://erlang-china.org/start/mochiweb_intro.html

做了一个简单的comet测试,在firefox下浏览时发现每个http请求处理的process id固定在2个,而且进程字典的数据也可以跨请求共享,找了下mochiweb的源码,发现其在http请求结束时,支持tcp连接复用(http1.1),代码如下:

mochiweb_http.erl

Erlang代码
  1. after_response(Body, Req) ->
  2. Socket = Req:get(socket),
  3. case Req:should_close() of
  4. true ->
  5. gen_tcp:close(Socket),
  6. exit(normal);
  7. false ->
  8. Req:cleanup(),
  9. ?MODULE:loop(Socket, Body)
  10. end.

mochiweb_request.erl

Erlang代码
  1. %% @spec should_close() -> bool()
  2. %% @doc Return true if the connection must be closed. If false, using
  3. %% Keep-Alive should be safe.
  4. should_close() ->
  5. ForceClose = erlang:get(mochiweb_request_force_close) =/= undefined,
  6. DidNotRecv = erlang:get(mochiweb_request_recv) =:= undefined,
  7. ForceClose orelse Version < {1, 0}
  8. %% Connection: close
  9. orelse get_header_value("connection") =:= "close"
  10. %% HTTP 1.0 requires Connection: Keep-Alive
  11. orelse (Version =:= {1, 0}
  12. andalso get_header_value("connection") =/= "Keep-Alive")
  13. %% unread data left on the socket, can't safely continue
  14. orelse (DidNotRecv
  15. andalso get_header_value("content-length") =/= undefined
  16. andalso list_to_integer(get_header_value("content-length")) > 0)
  17. orelse (DidNotRecv
  18. andalso get_header_value("transfer-encoding") =:= "chunked").

So, it's clear now.

2010年5月11日星期二

erlang学习笔记 跨系统erlang查询脚本

1.利用 os:cmd 执行命令进行查询
2.利用 os:type 检查os版本, 对于不同操作系统的不同做不不同的处理
3 os:getpid, 获得自身的进程号

-module(fd).
-export([start/0]).

get_total_fd_ulimit() ->
{MaxFds, _} = string:to_integer(os:cmd("ulimit -n")),
MaxFds.

get_total_fd() -> get_total_fd(os:type()).

get_total_fd({unix, Os})
when Os =:= linux orelse
Os =:= darwin orelse
Os =:= freebsd orelse Os =:= sunos ->
get_total_fd_ulimit();
get_total_fd(_) -> unknown.

get_used_fd_lsof() ->
Lsof = os:cmd("lsof -d \"0-9999999\" -lna -p " ++
os:getpid()),
string:words(Lsof, $\n).

get_used_fd() -> get_used_fd(os:type()).

get_used_fd({unix, Os})
when Os =:= linux orelse
Os =:= darwin orelse Os =:= freebsd ->
get_used_fd_lsof();
get_used_fd(_) -> unknown.

start()->
io:format("total fd: ~p~n"
"used fd: ~p~n", [get_total_fd(), get_used_fd()]),
halt(0).

2010年5月5日星期三

erlang sys调试(转)

转:http://www.erlang.org/doc/man/erlang.html
6 Sys and Proc_Lib

The module sys contains functions for simple debugging of processes implemented using behaviours.

There are also functions that, together with functions in the module proc_lib, can be used to implement a special process, a process which comply to the OTP design principles without making use of a standard behaviour. They can also be used to implement user defined (non-standard) behaviours.

Both sys and proc_lib belong to the STDLIB application.

6.1 Simple Debugging

The module sys contains some functions for simple debugging of processes implemented using behaviours. We use the code_lock example from the gen_event chapter to illustrate this:

% erl
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
Eshell V5.2.3.6 (abort with ^G)
1> code_lock:start_link([1,2,3,4]).
{ok,<0.32.0>}
2> sys:statistics(code_lock, true).
ok
3> sys:trace(code_lock, true).
ok
4> code_lock:button(4).
*DBG* code_lock got event {button,4} in state closed
ok
*DBG* code_lock switched to state closed
5> code_lock:button(3).
*DBG* code_lock got event {button,3} in state closed
ok
*DBG* code_lock switched to state closed
6> code_lock:button(2).
*DBG* code_lock got event {button,2} in state closed
ok
*DBG* code_lock switched to state closed
7> code_lock:button(1).
*DBG* code_lock got event {button,1} in state closed
ok
OPEN DOOR
*DBG* code_lock switched to state open
*DBG* code_lock got event timeout in state open
CLOSE DOOR
*DBG* code_lock switched to state closed
8> sys:statistics(code_lock, get).
{ok,[{start_time,{{2003,6,12},{14,11,40}}},
{current_time,{{2003,6,12},{14,12,14}}},
{reductions,333},
{messages_in,5},
{messages_out,0}]}
9> sys:statistics(code_lock, false).
ok
10> sys:trace(code_lock, false).
ok
11> sys:get_status(code_lock).
{status,<0.32.0>,
{module,gen_fsm},
[[{'$ancestors',[<0.30.0>]},
{'$initial_call',{gen,init_it,
[gen_fsm,<0.30.0>,<0.30.0>,
{local,code_lock},
code_lock,
[1,2,3,4],
[]]}}],
running,<0.30.0>,[],
[code_lock,closed,{[],[1,2,3,4]},code_lock,infinity]]}
6.2 Special Processes

This section describes how to write a process which comply to the OTP design principles, without making use of a standard behaviour. Such a process should:

be started in a way that makes the process fit into a supervision tree,
support the sys debug facilities, and
take care of system messages.
System messages are messages with special meaning, used in the supervision tree. Typical system messages are requests for trace output, and requests to suspend or resume process execution (used during release handling). Processes implemented using standard behaviours automatically understand these messages.

Example

The simple server from the Overview chapter, implemented using sys and proc_lib so it fits into a supervision tree:

-module(ch4).
-export([start_link/0]).
-export([alloc/0, free/1]).
-export([init/1]).
-export([system_continue/3, system_terminate/4,
write_debug/3]).
start_link() ->
proc_lib:start_link(ch4, init, [self()]).
alloc() ->
ch4 ! {self(), alloc},
receive
{ch4, Res} ->
Res
end.
free(Ch) ->
ch4 ! {free, Ch},
ok.
init(Parent) ->
register(ch4, self()),
Chs = channels(),
Deb = sys:debug_options([]),
proc_lib:init_ack(Parent, {ok, self()}),
loop(Chs, Parent, Deb).
loop(Chs, Parent, Deb) ->
receive
{From, alloc} ->
Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
ch4, {in, alloc, From}),
{Ch, Chs2} = alloc(Chs),
From ! {ch4, Ch},
Deb3 = sys:handle_debug(Deb2, {ch4, write_debug},
ch4, {out, {ch4, Ch}, From}),
loop(Chs2, Parent, Deb3);
{free, Ch} ->
Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
ch4, {in, {free, Ch}}),
Chs2 = free(Ch, Chs),
loop(Chs2, Parent, Deb2);
{system, From, Request} ->
sys:handle_system_msg(Request, From, Parent,
ch4, Deb, Chs)
end.
system_continue(Parent, Deb, Chs) ->
loop(Chs, Parent, Deb).
system_terminate(Reason, Parent, Deb, Chs) ->
exit(Reason).
write_debug(Dev, Event, Name) ->
io:format(Dev, "~p event = ~p~n", [Name, Event]).
Example on how the simple debugging functions in sys can be used for ch4 as well:

% erl
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]
Eshell V5.2.3.6 (abort with ^G)
1> ch4:start_link().
{ok,<0.30.0>}
2> sys:statistics(ch4, true).
ok
3> sys:trace(ch4, true).
ok
4> ch4:alloc().
ch4 event = {in,alloc,<0.25.0>}
ch4 event = {out,{ch4,ch1},<0.25.0>}
ch1
5> ch4:free(ch1).
ch4 event = {in,{free,ch1}}
ok
6> sys:statistics(ch4, get).
{ok,[{start_time,{{2003,6,13},{9,47,5}}},
{current_time,{{2003,6,13},{9,47,56}}},
{reductions,109},
{messages_in,2},
{messages_out,1}]}
7> sys:statistics(ch4, false).
ok
8> sys:trace(ch4, false).
ok
9> sys:get_status(ch4).
{status,<0.30.0>,
{module,ch4},
[[{'$ancestors',[<0.25.0>]},{'$initial_call',{ch4,init,[<0.25.0>]}}],
running,<0.25.0>,[],
[ch1,ch2,ch3]]}
Starting the Process

A function in the proc_lib module should be used to start the process. There are several possible functions, for example spawn_link/3,4 for asynchronous start and start_link/3,4,5 for synchronous start.

A process started using one of these functions will store information that is needed for a process in a supervision tree, for example about the ancestors and initial call.

Also, if the process terminates with another reason than normal or shutdown, a crash report (see SASL User's Guide) is generated.

In the example, synchronous start is used. The process is started by calling ch4:start_link():

start_link() ->
proc_lib:start_link(ch4, init, [self()]).
ch4:start_link calls the function proc_lib:start_link. This function takes a module name, a function name and an argument list as arguments and spawns and links to a new process. The new process starts by executing the given function, in this case ch4:init(Pid), where Pid is the pid (self()) of the first process, that is the parent process.

In init, all initialization including name registration is done. The new process must also acknowledge that it has been started to the parent:

init(Parent) ->
...
proc_lib:init_ack(Parent, {ok, self()}),
loop(...).
proc_lib:start_link is synchronous and does not return until proc_lib:init_ack has been called.

Debugging

To support the debug facilites in sys, we need a debug structure, a term Deb which is initialized using sys:debug_options/1:

init(Parent) ->
...
Deb = sys:debug_options([]),
...
loop(Chs, Parent, Deb).
sys:debug_options/1 takes a list of options as argument. Here the list is empty, which means no debugging is enabled initially. See sys(3) for information about possible options.

Then for each system event that we want to be logged or traced, the following function should be called.

sys:handle_debug(Deb, Func, Info, Event) => Deb1
Deb is the debug structure.

Func is a tuple {Module, Name} (or a fun) and should specify a (user defined) function used to format trace output. For each system event, the format function is called as Module:Name(Dev, Event, Info), where:

Dev is the IO device to which the output should be printed. See io(3).

Event and Info are passed as-is from handle_debug.

Info is used to pass additional information to Func, it can be any term and is passed as-is.

Event is the system event. It is up to the user to define what a system event is and how it should be represented, but typically at least incoming and outgoing messages are considered system events and represented by the tuples {in,Msg[,From]} and {out,Msg,To}, respectively.

handle_debug returns an updated debug structure Deb1.

In the example, handle_debug is called for each incoming and outgoing message. The format function Func is the function ch4:write_debug/3 which prints the message using io:format/3.

loop(Chs, Parent, Deb) ->
receive
{From, alloc} ->
Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
ch4, {in, alloc, From}),
{Ch, Chs2} = alloc(Chs),
From ! {ch4, Ch},
Deb3 = sys:handle_debug(Deb2, {ch4, write_debug},
ch4, {out, {ch4, Ch}, From}),
loop(Chs2, Parent, Deb3);
{free, Ch} ->
Deb2 = sys:handle_debug(Deb, {ch4, write_debug},
ch4, {in, {free, Ch}}),
Chs2 = free(Ch, Chs),
loop(Chs2, Parent, Deb2);
...
end.
write_debug(Dev, Event, Name) ->
io:format(Dev, "~p event = ~p~n", [Name, Event]).
Handling System Messages

System messages are received as:

{system, From, Request}
The content and meaning of these messages do not need to be interpreted by the process. Instead the following function should be called:

sys:handle_system_msg(Request, From, Parent, Module, Deb, State)
This function does not return. It will handle the system message and then call:

Module:system_continue(Parent, Deb, State)
if process execution should continue, or:

Module:system_terminate(Reason, Parent, Deb, State)
if the process should terminate. Note that a process in a supervision tree is expected to terminate with the same reason as its parent.

Request and From should be passed as-is from the system message to the call to handle_system_msg.
Parent is the pid of the parent.
Module is the name of the module.
Deb is the debug structure.
State is a term describing the internal state and is passed to system_continue/system_terminate.
In the example:

loop(Chs, Parent, Deb) ->
receive
...
{system, From, Request} ->
sys:handle_system_msg(Request, From, Parent,
ch4, Deb, Chs)
end.
system_continue(Parent, Deb, Chs) ->
loop(Chs, Parent, Deb).
system_terminate(Reason, Parent, Deb, Chs) ->
exit(Reason).
If the special process is set to trap exits, note that if the parent process terminates, the expected behavior is to terminate with the same reason:

init(...) ->
...,
process_flag(trap_exit, true),
...,
loop(...).
loop(...) ->
receive
...
{'EXIT', Parent, Reason} ->
..maybe some cleaning up here..
exit(Reason);
...
end.
6.3 User-Defined Behaviours

To implement a user-defined behaviour, write code similar to code for a special process but calling functions in a callback module for handling specific tasks.

If it is desired that the compiler should warn for missing callback functions, as it does for the OTP behaviours, implement and export the function:

behaviour_info(callbacks) ->
[{Name1,Arity1},...,{NameN,ArityN}].
where each {Name,Arity} specifies the name and arity of a callback function.

When the compiler encounters the module attribute -behaviour(Behaviour). in a module Mod, it will call Behaviour:behaviour_info(callbacks) and compare the result with the set of functions actually exported from Mod, and issue a warning if any callback function is missing.

Example:

%% User-defined behaviour module
-module(simple_server).
-export([start_link/2,...]).
-export([behaviour_info/1]).
behaviour_info(callbacks) ->
[{init,1},
{handle_req,1},
{terminate,0}].
start_link(Name, Module) ->
proc_lib:start_link(?MODULE, init, [self(), Name, Module]).
init(Parent, Name, Module) ->
register(Name, self()),
...,
Dbg = sys:debug_options([]),
proc_lib:init_ack(Parent, {ok, self()}),
loop(Parent, Module, Deb, ...).
...
In a callback module:

-module(db).
-behaviour(simple_server).
-export([init/0, handle_req/1, terminate/0]).
...

2010年4月30日星期五

erlang 数值计算

7.12 Arithmetic Expressions

op Expr
Expr1 op Expr2
op Description Argument type
+ unary + number
- unary - number
+ number
- number
* number
/ floating point division number
bnot unary bitwise not integer
div integer division integer
rem integer remainder of X/Y integer
band bitwise and integer
bor bitwise or integer
bxor arithmetic bitwise xor integer
bsl arithmetic bitshift left integer
bsr bitshift right integer
Table 7.2: Arithmetic Operators.

2010年4月14日星期三

alarm_handler

alarm_handler

MODULE

alarm_handler

MODULE SUMMARY

An Alarm Handling Process

DESCRIPTION

The alarm handler process is a gen_event event manager process which receives alarms in the system. This process is not intended to be a complete alarm handler. It defines a place to which alarms can be sent. One simple event handler is installed in the alarm handler at start-up, but users are encouraged to write and install their own handlers.

The simple event handler sends all alarms as info reports to the error logger, and saves all of them in a list which can be passed to a user defined event handler, which may be installed at a later stage. The list can grow large if many alarms are generated. So it is a good reason to install a better user defined handler.

There are functions to set and clear alarms. The format of alarms are defined by the user. For example, an event handler for SNMP could be defined, together with an alarm MIB.

The alarm handler is part of the SASL application.

When writing new event handlers for the alarm handler, the following events must be handled:

{set_alarm, {AlarmId, AlarmDescr}}

This event is generated by alarm_handler:set_alarm({AlarmId, AlarmDecsr}).

{clear_alarm, AlarmId}

This event is generated by alarm_handler:clear_alarm(AlarmId).

The default simple handler is called alarm_handler and it may be exchanged by calling gen_event:swap_handler/3 as gen_event:swap_handler(alarm_handler, {alarm_handler, swap}, {NewHandler, Args}). NewHandler:init({Args, {alarm_handler, Alarms}}) is called. Refer to gen_event(3) for further details.

EXPORTS

clear_alarm(AlarmId) -> void()

Types:

AlarmId = term()

Clears all alarms with id AlarmId.

get_alarms() -> [alarm()]

Returns a list of all active alarms. This function can only be used when the simple handler is installed.

set_alarm(alarm())

Types:

alarm() = {AlarmId, AlarmDescription}
AlarmId = term()
AlarmDescription = term()

Sets an alarm with id AlarmId. This id is used at a later stage when the alarm is cleared.

See Also

error_logger(3), gen_event(3)

2010年4月12日星期一

erlang 常用 misc(补充ing)

erlang:which(file). 对于已经加载到系统中的所有模块, 都可以定位它们的文件位置, 也可用它来了解是否已经加载此模块

rb 系列 rb:start/0 rb:start/1 rb:list/0 rb:list/1 rb:show/1 rb:grep/1
其中 rb:list(error) rb:show(error) 比较好用

ets:tab2list/1: 查看ets 数据太方便了
mnesia:table_info/2 查看mnesia table 信息
mnesia:sync_transaction 分布式开发时比较好用, 避免其它节点负载过大造成的影响

关于eralng性能调优必看的帖子 http://www.javaeye.com/topic/107476

2010年4月1日星期四

erlang 获取环境信息命令

code:get_path(). %获取当前加载路径的设定值
code:lib_dir(rpcengine, ebin). %获取库位置
code:all_loaded(). %返回所有已经
init:get_argument(home). init:get_arguments().
例如:
% erl -a b c -a d
...
1> init:get_argument(a).
{ok,[["b","c"],["d"]]}

erlang 获取自定义属性信息

xxx:module_info(). %module_info 是每次模块在编译时自动创建
beam_lib("xxxx.beam", [attributes]).chunkid() = "Abst" | "Attr" | "CInf"
chunkid() = "Abst" | "Attr" | "CInf"
| "ExpT" | "ImpT" | "LocT"
| "Atom"
chunkname() = abstract_code | attributes | compile_info
| exports | labeled_exports
| imports | indexed_imports
| locals | labeled_locals
| atoms

chunkref() = chunkname() | chunkid()
chunks(Beam, [ChunkRef]) -> {ok, {Module, [ChunkData]}} | {error, beam_lib, Reason}

2009年12月22日星期二

erl 命令

1. erl -pa 后边尽可能跟 绝对路径. 这是个很容易出错的点