http://hje.iteye.com/blog/1211734

应用的概念¶ 
当我们写了实现特定功能的代码之后,我们可能想将代码转成一个 应用 (application),这是可以作为一个单元启动和停止的组建,同时它也可以在其他系统中被重用。

我们要创建一个 应用回调模块 ,其中描述了该应用应该如何被启动和停止。

然后,需要一个应用规格,它被放在一个 应用资源文件 。我们还指定该应用由哪些模块组成,以及各个回掉模块的名字。

如果我们使用 systools ——Erlang/OTP用于打包的代码(参见 发布 ),每个应用的代码都可以按照预定的 目录结构 放在单独的目录中。

应用回调模块¶ 
如何启动和停止应用的代码,即监督树,由以下两个回掉函数来描述:

start(StartType, StartArgs) -> {ok, Pid} | {ok, Pid, State} 
stop(State) 
当要通过启动顶层督程来创建监督树的时候,会调用 start 。它要返回顶层督程的pid和一个选项值 State ,默认为 []。这个值会原样传递给 stop 。

StartType 通常是原子 normal 。只有在接管或故障转移中才会有其他值,参见 分布式应用 。 StartArgs 由 应用资源文件 中的键 mod 来定义。

在应用被停止之后会调用 stop/1 来进行必须的清除工作。注意应用实际的停止过程,也就是监督树的关闭,是按照 启动和停止应用 中所描述的方式自动处理的。

以下是一个例子,将来自 督程 一章中的督程打包为一个应用回调模块:

-module(ch_app). 
-behaviour(application).

-export([start/2, stop/1]).

start(_Type, _Args) -> 
    ch_sup:start_link().

stop(_State) -> 
    ok. 
一个库应用——不能被启动或者停止——则无须任何应用回调模块。

应用资源文件¶ 
我们通过创建一个放在应用资源文件——简称 .app 文件——中的应用规格来定义一个应用:

{application, Application, [Opt1,...,OptN]}. 
Application 是一个代表应用的名称的原子。文件必须被命名成 Application.app 。

每一个 Opt 都是一个定义了应用某种特性的元组 {Key, Value} 。所有的键都是可选。忽略的键会使用默认的值。

例如,用于库应用 libapp 的最小化的 .app 文件的内容为:

{application, libapp, []}. 
对于像 ch_app 这样的监督树应用的最小化 .app 文件的内容为:

{application, ch_app, 
[{mod, {ch_app,[]}}]}. 
键 mod 定义了回调模块以及应用的启动参数,在这个例子中相应是 ch_app 和 []。这表示应用启动的时候会调用:

ch_app:start(normal, []) 
而当应用被停止的时候会调用:

ch_app:stop([]) 
当使用 systools 时,Erlang/OTP工具的打包代码(参见 发布 ),键 description、vsn、modules、registered 和 applications 则应该指定为:

{application, ch_app, 
[{description, "Channel allocator"}, 
  {vsn, "1"}, 
  {modules, [ch_app, ch_sup, ch3]}, 
  {registered, [ch3]}, 
  {applications, [kernel, stdlib, sasl]}, 
  {mod, {ch_app,[]}} 
]}. 
description 
简短描述,字符串。默认为 “”。 
vsn 
版本号,字符串。默认为”“。 
modules 
由该应用引入的所有模块。当生成启动脚本和tar文件时, systools 将用到这个列表。一个模块必须被定义于且仅于一个应用。默认为[]。 
registered 
应用中所有注册进程的名称。 systools 使用这个列表来探测在应用之间是否有名称冲突。默认为 []。 
applications 
所有在此应用之前必须启动的应用。 systools 使用该列表来生成正确的启动脚本。默认为 [],但是注意任何应用都要至少依赖于 kernel 和 stdlib 。 
应用资源文件的语法和内容在 app(4) 中有详细的描述。

目录结构¶ 
当使用 systools 对代码进行打包的时候,每个应用的代码都放在单独的目录中 lib/Application-Vsn ,其中 Vsn 是版本号。

即便没有用到 systools ,最好也要了解它,因为Erlang/OTP其自身是按照OTP原则进行打包的所以才有了这个目录结构。如果存在一个应用的多个版本,那么代码服务器(见 code(3) )会自动使用来自目录中版本号最高的代码。

应用目录结构当然也可以用于开发环境。版本号是可以忽略的。

应用目录有以下子目录:

•src 
•ebin 
•priv 
•include 
src 
包含Erlang源代码 
ebin 
包含Erlang目标代码—— beam 文件。 .app 文件也放在这里。 
priv 
用于应用专属文件。例如,C执行程序就放在这里。应该使用函数 code:priv_dir/1 来访问这个目录。 
include 
用于包含文件。 
应用控制器¶ 
当启动了Erlang运行时系统,作为Kernel应用的一些进程会被启动。其中一个进程是应用控制器进程,注册为 application_controller 。

所有对应用的操作都由应用控制器来协调。它通过模块 application 里的函数来暴露接口, 请参考 application(3) 。尤其要了解,应用可以被加载、卸载、启动和停止。

加载和卸载应用¶ 
在能启动一个应用之前,首先它必须被加载。应用控制器会读取在 .app 中的信息并存起来。

1> application:load(ch_app). 
ok 
2> application:loaded_applications(). 
[{kernel,"ERTS  CXC 138 10","2.8.1.3"}, 
{stdlib,"ERTS  CXC 138 10","1.11.4.3"}, 
{ch_app,"Channel allocator","1"}]被停止的或者从未启动过的应用,可以被卸载。该应用相关的信息会从应用控制器的内部数据库中删除。

3> application:unload(ch_app). 
ok 
4> application:loaded_applications(). 
[{kernel,"ERTS  CXC 138 10","2.8.1.3"}, 
{stdlib,"ERTS  CXC 138 10","1.11.4.3"}]Note: 
加载/卸载应用并不会加载/卸载该应用所使用的代码。代码加载是按照一般的方式进行的。

启动和停止应用¶ 
启动应用要调用:

5> application:start(ch_app). 
ok 
6> application:which_applications(). 
[{kernel,"ERTS  CXC 138 10","2.8.1.3"}, 
{stdlib,"ERTS  CXC 138 10","1.11.4.3"}, 
{ch_app,"Channel allocator","1"}]如果应用尚未被加载,那么应用控制器会首先使用 application:load/1 加载它。它会检查 applications 键对应的值,来确保要在该应用运行之前启动的应用都启动了。

然后应用控制器为应用创建一个应用主程序。它是该应用中所有进程的队长。应用主程序通过调用应用模块中的回调函数 start/2 启动应用(会给出由在 .app 文件中的 mod 建定义的启动参数)。

停止一个应用,但不卸载,可调用:

7> application:stop(ch_app). 
ok 
配置应用¶ 
可以使用配置参数来对应用进行配置。它们在 .app 文件中是一个由键 env 指定的 {Par, Val} 元组列表。

{application, ch_app, 
[{description, "Channel allocator"}, 
  {vsn, "1"}, 
  {modules, [ch_app, ch_sup, ch3]}, 
  {registered, [ch3]}, 
  {applications, [kernel, stdlib, sasl]}, 
  {mod, {ch_app,[]}}, 
  {env, [{file, "/usr/local/log"}]} 
]}. 
Par 必须是一个原子, Val 可以是任意值。应用可以通过调用 application:get_env(App, Par) 或一些其他类似函数来获取配置参数的值,参见 application(3) 。

例如:

% erl 
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]

Eshell V5.2.3.6  (abort with ^G) 
1> application:start(ch_app). 
ok 
2> application:get_env(ch_app, file). 
{ok,"/usr/local/log"}.app 文件中的值可以被系统配置文件中的值所覆盖。系统配置文件是一个包含相关应用的配置参数的文件。

[{Application1, [{Par11,Val11},...]}, 
..., 
{ApplicationN, [{ParN1,ValN1},...]}]. 
系统配置要被命名为 Name.config 并且要使用命令行参数 -config Name 来启动Erlang。更多信息参见 config(4) 。

例如:创建一个文件 test.config 包含一下内容:

[{ch_app, [{file, "testlog"}]}]. 
file 的值将覆盖在 .app 文件中所定义的 file 的值:

% erl -config test 
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]

Eshell V5.2.3.6  (abort with ^G) 
1> application:start(ch_app). 
ok 
2> application:get_env(ch_app, file). 
{ok,"testlog"}如果使用了 发布处理 ,那么只能使用一个系统配置文件同时该文件必须叫做 sys.config 。

在 .app 文件中的值,也包括系统配置文件中的值,都可以直接在命令行中被覆盖:

% erl -ApplName Par1 Val1 ... ParN ValN例如:

% erl -ch_app file '"testlog"' 
Erlang (BEAM) emulator version 5.2.3.6 [hipe] [threads:0]

Eshell V5.2.3.6  (abort with ^G) 
1> application:start(ch_app). 
ok 
2> application:get_env(ch_app, file). 
{ok,"testlog"}应用启动类型¶ 
当启动应用的时候要定义一个启动类型。

application:start(Application, Type) 
application:start(Application) 和调用 application:start(Application, temporary) 是一样的。类型还可以是 permanent 持久的或者 transient 过渡的:

•如果一个持久应用终止了,所有其他的应用以及运行时系统都会被终止。 
•如果一个过渡应用以 normal 理由终止了,那么这个信息会被上报但是不会终止其他应用。如果一个过渡应用异常终止了——即以非 normal 的理由终止了——那么其他应用以及运行时环境也会被终止。 
•如果一个临时(temporary)应用终止了,那么会报告该信息但不会终止其他应用。 
我们总是可以通过明确调用 application:stop/1 来停止一个应用。无论是什么模式,都不会影响其他应用。

注意在实践中很少使用过渡模式,因为当一个监督树终止了,退出理由会被设置为 shutdown ,而非 normal 。

http://erlang.shiningray.cn/otp-design-principles/applications.html

erlang app 文件的更多相关文章

  1. 给iOS 模拟器“安装”app文件

    前言 刚刚接触iOS的时候,我就一直很好奇,模拟器上面能不能直接安装app呢?如果可以,我们就直接在模拟器上面聊QQ和微信了.直到昨天和朋友们聊到了这个话题,没有想到还真的可以给模拟器“安装”app! ...

  2. rabbitmq .erlang.cookie文件疑惑

    1.安装方式常见的rabbitmq安装方式有两种:rpm安装和二进制安装(编译安装). 2..erlang.cookie是什么.erlang.cookie是erlang实现分布式的必要文件,erlan ...

  3. file not found app文件

    昨天svn迁移.然后又一次check out之后编译遇到这个错误. Ld Build/Products/Debug-iphonesimulator/wiseCloudCrmTests.xctest/w ...

  4. 企业级项目把.app文件转成.ipa文件的自动化实现

    将MakeIPA.sh添加到项目的根目录下 此脚本针对企业级项目打包,不会编译项目,在打包前确认项目已经编译完成生成了"XXX.app"文件 使用前需要配置该脚本部分路径才能正确打 ...

  5. 利用.dSYM跟.app文件准确定位Crash位置

     本文转载至  http://blog.csdn.net/lvxiangan/article/details/28102629       利用.dSYM和.app文件准确定位Crash位置首先,确保 ...

  6. fruitstrap 安装.app文件

    1. 下载ipa的ios文件然后解压成.app的文件 2. 进入fruitstrap文件夹,copy .app文件到fruitstrap文件夹中 执行./fruitstrap -b umetrip.a ...

  7. 【转】 利用.dSYM和.app文件准确定位Crash位置

    http://blog.csdn.net/jinzhu117/article/details/20615991 首先,确保在release(Ad Hoc或者App Store)一个版本时,保存了对应的 ...

  8. Xamarin App文件(apk)大小和启动时间的影响因素

    Xamarin开发的时候大家都有一个疑问,就是apk文件会不会特别的大,启动会不会很慢.答案是肯定的,文件肯定大,启动肯定会慢,但是具体大多少.具体慢多少,有什么因素可以使apk文件稍微小一点.可以使 ...

  9. Mac 下的 .app文件如何生成.dmg ?

    安装 Node.js最新版. 安装方法不赘述. 安装 create-dmg: sudo npm install --global create-dmg 注意这里 sudo不能少. 终端切换到 .app ...

随机推荐

  1. 使用Spring Security3的四种方法概述

    使用Spring Security3的四种方法概述 那么在Spring Security3的使用中,有4种方法: 一种是全部利用配置文件,将用户.权限.资源(url)硬编码在xml文件中,已经实现过, ...

  2. 让你更值钱的方法:培养稀缺(追逐新技术,淬炼已有技能、做到出类拔萃,寻找自己所在的行业痛点,App开发者是市场动态平衡的典型)

    一个开发者,如何才能更值钱? 答案非常简单:掌握稀缺资源. 那么,怎样才能持续不断地掌握稀缺资源,让自己更值钱呢? 请看接下来介绍的 2 种识别稀缺的方法和 2 种培养稀缺的策略. 稀缺资源的秘密 资 ...

  3. JS里的map与forEach遍历

    map 返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值. var numbers = [3,2,6,3] function func(num){ return num * documen ...

  4. POJ 3041 Asteroids 最小覆盖数

    http://poj.org/problem?id=3041 题目大意: 一辆宇宙飞船在一个小行星带中,你知道,这很危险.他有一种武器,可以清除掉一行或一列的小行星.问把小行星全部清除最少的武器使用次 ...

  5. Day2:模块初识

    一.模块(库) 别人写好的一堆功能,封装起来,你直接导入就可以用,就不用自己再写一次,使用import方法 二.分类:标准库与第三方库 标准库:免安装,导入即可使用,最常用的一些功能 第三方库:需要下 ...

  6. 在react底下安装环境

    1.在react底下安装环境 Image.png Image.png 2.新建一个文件夹 Image.png 3.配置入口文件redux:staticRoot+'/redux/app' Image.p ...

  7. Oracle 中的Interger类型

    引自 wolfAone, oracle有没有integer类型,这种类型的最大值是多少啊. Integer是Number类型的子类型: NUMBER Type You use the NUMBER d ...

  8. NSNotificationCenter消息通信(KVO)

    NSNotificationCenter是程序不同类间的消息通信. 注册消息通知: [[NSNotificationCenter defaultCenter]addObserver:self sele ...

  9. Oracle中暂时表空间的清理

    作者:iamlaosong Oracle暂时表空间主要用来做查询和存放一些缓冲区数据. 暂时表空间消耗的主要原因是须要对查询的中间结果进行排序.暂时表空间的主要作用: 索引create或rebuild ...

  10. Android NetworkOnMainThreadException异常

    看名字就应该知道,是网络请求在MainThread中产生的异常 先来看一下官网的解释: Class Overview The exception that is thrown when an appl ...