Chinaunix首页 | 论坛 | 博客
  • 博客访问: 132902
  • 博文数量: 12
  • 博客积分: 102
  • 博客等级: 入伍新兵
  • 技术积分: 150
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-25 09:03
个人简介

80后程序员

文章分类

全部博文(12)

文章存档

2020年(1)

2018年(3)

2013年(5)

2011年(1)

2010年(2)

我的朋友

分类: Erlang

2013-01-30 20:57:01

第一步,建立OTP应用目录结构
    demo
        |-doc
        |-ebin
        |-include
        |-src
    说明:
    (1) demo, 这是应用的名称, 也是项目的根目录.
    (2) doc, 用于存放文档, 可选.
    (3) ebin, 用户存放编译后的可执行文件(.beam), demo.app 元数据文件(application resource file)也存放于该目录下。
    (4) src, 顾名思义, 用于存放源代码.
    
第二步,构造.app文件, demo.app内容如下.     
 {application,       %(1)
    demo,            %(2)
        [            %(3)
        {description, "this is a test erlang project"},
        {vsn, "0.1.0"},
        {modules, [demo_app,
               demo_sup,
               demo_server]},
        {registered, [demo_sup]},
        {applications, [kernel, stdlib]},
        {mod, {demo_app, []}}]
    }.
    说明:该文件结构很简单, 由一个三元组成, {application, AppName, [Options]}, 该三元组叫应用描述(application specification).
    (1) application, 元组第一项
    (2) AppName, 即 demo, 应用的名称
    (3) [Options], 这是一个参数列表, 每个成员都是一个{key, Value}的结构.
    
第三步,构造一个应用行为模式demo.erl
    每个应用都要实现一个application行为(behaviour)的回调模块,它的作用有, 1 提供相应的start, stop接口,控制应用的启动停止, 2 负责启动应用的根监督者(root supervisour), 根监督者是应用中其它进程的鼻祖.
    下面是文件demo.erl的内容.
%%
%%  flagcugb@126.com
%% 
-module(demo_app).

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

start(_Type, _StartArgs) ->
    case demo_sup:start_link() of
        {ok, Pid} ->
            {ok, Pid};
        Error ->
            Error
    end.
stop(_State) ->
    ok.
    
第四步, 构造根监督者模块 demo_sup.erl
    应用是一棵由监督者和工作进程共同构成的进程树, 树根就是根监督者, 它的作用就是管理它的子进程, 如启动, 停止, 重启等.
-module(demo_sup).
-behaviour(supervisor).

-export([start_link/0]).
-export([init/1]).

-define(SERVER, ?MODULE).

start_link() ->
    supervisor:start_link({local, ?SERVER}, ?MODULE, []).

init([]) ->
    Server = {demo_server, {demo_server, start_link, []},
              permanent, 2000, worker, [demo_server]},
    Children = [Server],
    RestartSdemoategy = {one_for_one, 0, 1},
    {ok, {RestartSdemoategy, Children}}.
第五步, 实现工作者模块 demo_server.erl
    用 gen_server 来实现一个简单的工作者.    
%%% -------------------------------------------------------------------
%%% Author  : flagcugb@126.com
%%% Description : 每秒钟打印一个 Tic 信息
%%%
%%% -------------------------------------------------------------------
-module(demo_server).
-behaviour(gen_server).
-export([start_link/0, stop/0]).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-record(state, {}).

-define(LOOP_TIME, 1000).

%% @doc 启动一个gen_server
start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

stop() ->
    ok.

init([]) ->
    ok = start_tic_timer(),
    erlang:send_after(?LOOP_TIME, self(), {'tic'}),
    {ok, #state{}}.

handle_call(_Request, _From, State) ->
    Reply = ok,
    {reply, Reply, State}.

handle_cast(_Msg, State) ->
    {noreply, State}.

handle_info({'tic'}, State) ->
    ok = do_tic(),
    ok = start_tic_timer(),
    {noreply, State};
handle_info(_Info, State) ->
    {noreply, State}.
terminate(_Reason, _State) ->
    ok.
code_change(_OldVsn, State, _Exdemoa) ->
    {ok, State}.

%%-------------
%% internal API
%%-------------
do_tic() ->
    io:format("* Tic ~p~n", [calendar:local_time()]),
    ok.

start_tic_timer() ->
    erlang:send_after(?LOOP_TIME, self(), {'tic'}),
    ok.
第六步, 编译
    两种方法:
    (1) 直接编译
    erlc -o ebin src/*.erl
    (2) 借助makefile, 方便以后扩展, makefile内容如下
.PHONY:all clean

all:
	erlc -o ebin src/*.erl
	
clean:
	@echo "cleaning ... ..."
	-rm ebin/*.beam
	@echo "ok"

第七步, 启动

    erl -pa ebin
    >application:start(demo).



阅读(2940) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~