gen_server的State生命周期是怎样的

Nei*_*eil 3 erlang erlang-otp gen-server

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

参考Erlang gen_server通信

-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}).
Run Code Online (Sandbox Code Playgroud)

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

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

如果是这样,这个“State”是一个全局变量吗?这个“国家”什么时候才会被毁灭。

Erlang 有全局变量吗?

小智 6

您的直觉是正确的,尽管我认为值得指出的是,该变量在技术上State在任何地方都不相同,但它确实在任何地方都引用相同的。您的每个回调(即、等)都作为参数接收,并且它们必须返回(可能是新的)作为其结果的一部分。inti/1handle_call/3StateState

要理解它是如何工作的,您需要知道它的gen_server作用。以一种超级极其简单的方式,当你调用时 gen_server 正在做的gen_server:start_link/4是:

% 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
Run Code Online (Sandbox Code Playgroud)

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

希望这可以帮助 :)