转载:http://blog.csdn.net/krh2001/archive/2009/06/22/4287962.aspx
Erlang 系统原理
版本 5.7.1
翻译:krh2001
1 系统原理
一个Erlang 运行时系统可通过命令erl 来启动:
% erl
Erlang (BEAM) emulator version 5.2.3.5 [hipe] [threads:0]
Eshell V5.2.3.5 (abort with ^G)
1>
erl 解释执行从命令行方式输入的一到几行参数,参见erl(1) 。有几个命令也在本节中被描述。
通过调用函数init:get_argument(Key), 或者init:get_arguments() ,应用程序也能够访问从命令行执行命令所产生的变量的数值。
通过调用函数halt/0 ,1 可以终止运行时系统。参见erlang(3) 。
模块init 包含了用来再次启动(restarting) ,重新启动(rebooting) 和停止运行时系统的几个函数 。参见init(3) 。
init:restart()
init:reboot()
init:stop()
同时,如果Erlang shell 被终止,运行时系统也将终止。
运行时系统使用一个引导脚本 (boot script ) 来启动。引导脚本中包含一些指令,指出哪些代码被加载,哪些进程和程序被启动。
引导脚本文件具有扩展名:“.script ”。运行时系统使用的是一个编译过的二进制版本的引导脚本。这个二进制引导脚本 (binary boot script )文件具有扩展名:“.boot ”。
通过命令行参数-boot 来指出哪一个引导脚本将被使用。扩展名“.boot ”应该省略。例如,使用引导脚本“start_all.boot ”来启动:
% erl -boot start_all
如果没有指定一个引导脚本,缺省的引导脚本为“ROOT/bin/start ”,参见后面的缺省引导脚本的说明。
命令行参数-init_debug 将使初始化进程在解释执行引导脚本时输出一些调试信息:
% erl -init_debug
{progress,preloaded}
{progress,kernel_load_completed}
{progress,modules_loaded}
{start,heart}
{start,error_logger}
...
关于引导脚本的详细的语法和内容可参见script(4) 。
Erlang/OTP 自带有两个引导脚本:
start_clean.boot
加载和启动内核(Kernel )和标准库(STLLIB )应用程序。
start_sasl.boot
Loads the code for and starts the applications Kernel, STDLIB and SASL. 加载和启动内核(Kernel ),标准库(STDLIB )和SALS (System Architecture Support Libraries, 适合产品化的环境,支持错误日志,过载保护等)应用程序。
start_clear 和start_sasl 哪一个将被缺省使用取决于用户在安装Erlang/OTP 时的选择,当安装程序询问用户“Do you want to use a minimal system startup instead of the SASL startup ”(你是否使用一个最小系统启动来代替SASL 启动?)时如果回答yes (是),start_clean 将被用默认的引导脚本,否则默认使用start_sasl 。一份名称为“start.boot ”的以上所选择的脚本的拷贝被放到ROOT/bin 目录下。
创建一个用户定制的引导脚本有时是很有用的或者是必需的。当运行时Erlang 系统是嵌入式模式,这尤其正确。参见代码加载策略 。
手工编写一个引导脚本是可能的,然而推荐的方式是使用函数systools:make_script/1,2 从一个发布资源文件Name.rel 来创建,这需要源代码是符合OTP 设计原则结构的应用程序(该程序并非必需在带有OTP 应用程序的终端内启动,在纯(plain )Erlang 中也可以)。
在《OTP 设计原则》和erl(4) 可以读到更多关于.rel 文件的内容。
二进制格式的引导脚本文件Name.boot 是从引导脚本文件Name.script 通过使用函数systools:script2boot(File) 来生成的。
运行时系统既可以在嵌入模式 (embedded ) 也可以在交互 模式 (interactive ) 启动。这取决于命令行参数-mode 。
% erl -mode embedded
默认的模式是交互模式。
- 在嵌入模式,所有的代码将按照引导脚本在启动时被加载。(通过明确地命令代码服务器,也能够在运行时动态加载代码)。
- 在交互模式,代码在第一次被引用的时候动态地被加载。当调用一个已编译的模块内的函数,而该模块还没有被加载,代码服务器将搜索代码路径,并将模块加载到系统。
最初,代码路径包含当前的工作目录和所有位于ROOT/lib 下面的库的代码目录,ROOT 是Erlang/OTP 的安装目录。代码目录可能命名为Name[-Vsn] ,在那些具有相同的名称的中,代码服务器缺省选择版本最高的那个,后缀-Vsn 是可选的。如果在名称为Name[-Vsn] 的目录下有一个名字为ebin 的子目录,那么它就是那个被加到代码路径中的目录。
代码路径可以被扩充,使用命令行参数 -pa Directories 和 -pz Directories 。这些目录将分别被加到代码路径的开头或者结尾。例如:
% erl -pa /home/arne/mycode
代码服务器模块包含一些函数用来修改和检查代码搜索路径,参见code(3) 。
下列文件类型在Erlang/OTP 中被定义:
文件类型 |
文件名/ 扩展名 |
相关 文档 |
模块 |
.erl |
《Erlang 参考手册》 |
包含文件 |
.hrl |
《Erlang 参考手册》 |
发布资源文件 |
.rel |
rel(4) |
应用程序资源文件 |
.app |
app(4) |
引导脚本 |
.script |
script(4) |
二进制引导脚本 |
.boot |
- |
配置文件 |
.config |
config(4) |
应用程序升级文件 |
.appup |
appup(4) |
发布升级文件 |
.relup |
relup(4) |
Copyright © 1991-2009 Ericsson AB
来自运行时系统的错误信息,通常是关于一个进程由于发生一个未被捕获的异常而终止的信息,在缺省情况下,将被写到终端(TTY ):
=ERROR REPORT==== 9-Dec-2003::13:25:02 ===
Error in process <0.27.0> with exit value: {{badmatch,[1,2,3]},[{m,f,1},{shell,eval_loop,2}]}
一个系统进程被注册为错误日志记录者 ,错误信息将被错误日志记录者所接收和记录。该进程接收所有的错误消息,这些消息来自Erlang 运行时系统,也可以来自不同于Erlang/OTP 应用程序的那些标准行为。
运行时系统所使用的退出原因(例如上面的badarg ),在《Erlang 参考手册》中“错误和错误捕获”中详细描述。
进程错误日志记录者和它的用户接口(具有相同的名字),在error loger(3) 中描述。系统允许被配置成让错误信息写入文件或者(同时)从终端(TTY )输出。而且,应用程序也可以发送一个格式化的错误信息到错误日志记录者。
标准的行为(supervisor, gen_server, 等)发送进度和错误信息到日志。如果SASL 应用程序被启动,这些信息也将被写到终端。更多的信息请参见《SASL 用户手册》中的SASL 错误日志。
% erl -boot start_sasl
Erlang (BEAM) emulator version 5.4.13 [hipe] [threads:0] [kernel-poll]
=PROGRESS REPORT==== 31-Mar-2006::12:45:58 ===
supervisor: {local,sasl_safe_sup}
started: [{pid,<0.33.0>},
{name,alarm_handler},
{mfa,{alarm_handler,start_link,[]}},
{restart_type,permanent},
{shutdown,2000},
{child_type,worker}]
=PROGRESS REPORT==== 31-Mar-2006::12:45:58 ===
supervisor: {local,sasl_safe_sup}
started: [{pid,<0.34.0>},
{name,overload},
{mfa,{overload,start_link,[]}},
{restart_type,permanent},
{shutdown,2000},
{child_type,worker}]
=PROGRESS REPORT==== 31-Mar-2006::12:45:58 ===
supervisor: {local,sasl_sup}
started: [{pid,<0.32.0>},
{name,sasl_safe_sup},
{mfa,{supervisor,
start_link,
[{local,sasl_safe_sup},sasl,safe]}},
{restart_type,permanent},
{shutdown,infinity},
{child_type,supervisor}]
=PROGRESS REPORT==== 31-Mar-2006::12:45:58 ===
supervisor: {local,sasl_sup}
started: [{pid,<0.35.0>},
{name,release_handler},
{mfa,{release_handler,start_link,[]}},
{restart_type,permanent},
{shutdown,2000},
{child_type,worker}]