什么是gen_server的状态生命周期

时间:2017-11-02 23:59:46

标签: erlang otp gen-server

我是Erlang的新学员,我对Erlang变量的生命周期有疑问。

来自Erlang gen_server comunication

的参考资料
-module(wy).
-compile(export_all).
-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]).
-behaviour(gen_server).
-record(state, {id ,m, succ, pred}).

start(Name, M) ->
    gen_server:start_link({local, Name}, ?MODULE, [Name, M], []).

init([Name, M]) ->
    {ok, #state{id = Name, m = M}}.

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

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

handle_info(_Info, State) ->
    {noreply, State}.

terminate(_Reason, _State) ->
    ok.

code_change(_OldVsn, State, _Extra) ->
    {ok, State}.


get_server_info(ServerName) ->
    gen_server:call(ServerName, {get_server_info}).

什么是变量“状态”生命周期?

我们可以看到变量“State”从handle_call和handle_cast重用。首先,这些“状态”是否与init()函数"#state{id = Name, m = M}"初始化相同?

如果是这样,这个“状态”是全局变量吗?这个“国家”何时会被摧毁。

Erlang是否有全局变量?

2 个答案:

答案 0 :(得分:3)

你的直觉是正确的,虽然我认为值得指出变量State 技术上在各处都不一样但它确实引用相同的无处不在。您的每个回调(即inti/1handle_call/3等)都会收到State作为参数,并且必须返回(可能是新的)State作为其结果的一部分。

要了解其工作原理,您需要了解gen_server的作用。以极其过于简单的方式,当您致电gen_server:start_link/4时,gen_server正在执行的操作是:

% Ignoring stuff here, for simplicity
start_link(_Name, Mod, InitArg, _Options) ->
  spawn(
    fun() ->
      {ok, State} = Mod:init(InitArg),
      loop(Mod, State) %% This is where the result of your init/1 function goes
    end).

loop(Mod, State) ->
  NextState =
    receive
      {call, From, Msg} ->
        % Here, it gives you the current state and expects you to return
        % a new one.
        {reply, Reply, NewState} = Mod:handle_call(Msg, From, State),
        NewState;
      {cast, Msg} ->
        % Here, it gives you the current state and expects you to return
        % a new one.
        {noreply, NewState} = Mod:handle_cast(Msg, State),
        NewState;
      Info ->
        % Here, it gives you the current state and expects you to return
        % a new one.
        {noreply, NewState} = Mod:handle_info(Msg, State),
        NewState;
      {stop, Reason} ->
        Mod:terminate(Reason, State),
        exit(Reason)
    end,
  loop(Mod, NextState). % Then it keeps on looping with the new state

正如您所看到的,State的值是gen_server进程的本地值,它被传递给每个回调并且它的被替换以及每个回调的结果保持循环直到服务器终止。 当然,gen_server的代码并不那么简单(This talk为此提供了很好的解释 - 用西班牙语,我知道,对不起)。

希望这会有所帮助:)

答案 1 :(得分:0)

状态是gen_server的内部状态。状态可以是任何东西,数据结构的单个变量(映射,记录或列表),在这种情况下是记录。如果已经定义了一组值,则使用记录,否则我们可以使用映射。

是的,State将在init()函数中初始化并将作为参数在每个回调中传递,您可以根据需要简单地更新State值,并在每次回调中发送回复时设置为新状态。

如果gen服务器被杀或正常退出,状态将与gen_server进程一起销毁。当退出时原因正常终止/ 3回调将被调用。