gen_server 的状态生命周期是什么

What is the gen_server's State life cycle

我是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" 生命周期?

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

如果是,这个"State"是全局变量吗?这个"State"什么时候销毁

Erlang 有全局变量吗?

状态是gen_server的内部状态。状态可以是任何东西,从单个变量到数据结构(映射、记录或列表),在本例中是一条记录。如果您定义了一组值,则使用记录,否则我们可以使用映射。

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

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

你的直觉是正确的,虽然我认为值得指出的是变量 State 技术上 各地不一样,但它确实引用了相同的 无处不在。您的每个回调(即 inti/1handle_call/3 等)都接收 State 作为参数,并且它们必须 return 一个(可能是新的)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 对此提供了很好的解释 - 西班牙文,抱歉,我知道)。

希望这对您有所帮助:)