美文网首页
erlang gen server例子详解

erlang gen server例子详解

作者: 码农工号9527 | 来源:发表于2019-05-29 20:29 被阅读0次

    实现简单的bank系统 创建用户 存钱 取钱

    -module(my_bank).
    -behaviour(gen_server).
    -export([init/1,handle_call/3,handle_cast/2,handle_info/2,terminate/2,code_change/3]).
    -export([start/0,stop/0,new_account/1,deposit/2,withdraw/2]).
    -define(SERVER,?MODULE).
    % 启动一个名为{local my_bank}本地服务器, 回调模块为my_bank
    start() -> gen_server:start_link({local, ?SERVER}, ?MODULE, [], []).
    % 对远程服务器的调用  关闭服务器 Msg是stop
    stop() -> gen_server:call(?MODULE, stop).
    % 对远程服务器的调用 给进程发送同步消息 Msg是{new,Who}
    new_account(Who) -> gen_server:call(?MODULE,{new,Who}).
    % 对远程服务器的调用 给进程发送同步消息 Msg是{add, Who, Amount}
    deposit(Who,Amount) -> gen_server:call(?MODULE,{add, Who, Amount}).
    % 对远程服务器的调用 给进程发送同步消息 Msg是{remove,Who,Amount}
    withdraw(Who,Amount) -> gen_server:call(?MODULE,{remove,Who,Amount}).
    %启动本地服务器后第一个调用的回调模块方法  返回{ok,State}说明成功启动服务器 State为handle_call/3的第三个参数
    init([]) -> {ok,ets:new(?MODULE,[])}.
    % handle_call 处理的格式
    % spec handle_call(Request, From, Statu) ->
    %                                   {reply, Reply, State} |
    %                                   {reply, Reply, Statu, Timeout} |
    %                                   {noreply, State} |
    %                                   {noreply, State, TimeOut} |
    %                                   {stop, Reason, Reply, State} |
    %                                   {stop, Reason, State}
    % 同步的回调函数 处理格式{reply, Reply, State}
    handle_call({new, Who}, _From, Tab) ->
        Reply = case ets:lookup(Tab,Who) of
            [] -> ets:insert(Tab,{Who,0}),
                {welcome,Who};
            [_] -> {Who, you_already_are_a_customer}
        end,
        {reply, Reply, Tab};
    % 同步的回调函数 处理格式{reply, Reply, State}
    handle_call({add,Who,X}, _From, Tab) ->
        Reply = case ets:lookup(Tab, Who) of
            [] -> not_a_customer;
            [{Who,Balance}] ->
                NewBalance = Balance + X,
                ets:insert(Tab,{Who,NewBalance}),
                {thanks, Who, your_balance_is, NewBalance}
        end,
        {reply,Reply,Tab};
    % 同步的回调函数 处理格式{reply, Reply, State}
    handle_call({remove, Who, X}, _From, Tab) ->
        Reply = case ets:lookup(Tab,Who) of
            [] -> not_a_customer;
            [{Who,Balance}] when X =< Balance ->
                NewBalance = Balance - X,
                ets:insert(Tab,{Who,NewBalance}),
                {thanks, Who, your_balance_is, NewBalance};
            [{Who, Balance}] ->
                {sorry, Who, you_only_have, Balance, in_the_bank}
        end,
        {reply,Reply,Tab};
    % 同步的回调函数 停止服务器  处理格式{stop, Reason, Reply, State} 第二个参数normal被用作terminate/2的第一个参数 第三个参数作为my_bank:stop/0的返回值
    handle_call(stop, _From, Tab) -> {stop, normal, stopped, Tab}.
    % handle_cast 处理的格式
    % spec handle_cast(Msg, Statu) ->
    %                       {noreply, State} |
    %                       {noreply, State, TimeOut} |
    %                       {stop, Reason, State}
    % 异步的回调函数 处理格式{noreply, State}
    handle_cast(_Msg, State) -> {noreply, State}.
    % handle_info 处理的格式
    % spec handle_info(Msg, Statu) ->
    %                       {noreply, State} |
    %                       {noreply, State, TimeOut} |
    %                       {stop, Reason, State}
    % 原生消息 不通过call或cast,直接发往服务器进程的消息 如:{'EXIT', Pid, Why} 或者知道此服务器pid的进程直接发过来的消息
    handle_info(_Info, State) -> {noreply, State}.
    % 以handle_开头的回调收到{stop, Reason, State} | {stop, Reason, Reply, State},或者服务器奔溃生成{'EXIT',reason},会调用此回调函数
    terminate(_Reason, _State) -> ok.
    % 再代码更改时转换进程状态
    code_change(_OldVsn, State, _Extra) -> {ok, State}.
    

    相关文章

      网友评论

          本文标题:erlang gen server例子详解

          本文链接:https://www.haomeiwen.com/subject/xfputctx.html