Erlang 什么是gen#u服务器&x27;s状态生命周期

Erlang 什么是gen#u服务器&x27;s状态生命周期,erlang,otp,gen-server,Erlang,Otp,Gen Server,我是Erlang的新手,我对Erlang变量的生命周期有疑问 参考自 什么是可变的“状态”生命周期 我们可以看到变量“State”是从handle\u调用和handle\u cast中重用的。首先,这些“状态”是否与从init()函数“#State{id=Name,m=m}”初始化的状态相同 如果是,这个“状态”是全局变量吗?这个“国家”什么时候会被摧毁 Erlang是否具有全局变量?状态是gen_服务器的内部状态。状态可以是任何东西,数据结构的单个变量(映射、记录或列表),在本例中为记录。如果

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

参考自

什么是可变的“状态”生命周期

我们可以看到变量“State”是从handle\u调用和handle\u cast中重用的。首先,这些“状态”是否与从init()函数
“#State{id=Name,m=m}”
初始化的状态相同

如果是,这个“状态”是全局变量吗?这个“国家”什么时候会被摧毁


Erlang是否具有全局变量?

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

是的,状态将在init()函数中初始化,并在每个回调中作为参数传递,您只需根据需要更新状态值,并在每个回调中发送应答时将其设置为新状态


如果gen_服务器正常关闭或退出,则状态将随gen_服务器进程一起销毁。当有原因退出时,将调用正常终止/3回调

您的直觉是正确的,尽管我认为值得指出的是,变量
State
在技术上并非处处相同,但它确实处处引用相同的值。每个回调(即
inti/1
handle\u call/3
等)都将
状态作为参数接收,并且它们必须返回一个(可能是新的)
状态作为其结果的一部分

要了解其工作原理,您需要了解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
如您所见,
状态的值
是gen_服务器进程的本地值,它被传递到每个回调,并被每个回调的结果替换,以保持循环,直到服务器终止。 当然,gen_服务器的代码并没有那么简单(这提供了一个很好的解释——用西班牙语,我知道,对不起)


希望这有帮助:)

谢谢你,布鲁乔。我还有一个后续问题。当从不同流程同时调用、转换、信息、设置状态时,状态是否会捕获来自不同流程的所有更改?当cast()将值A设置为状态时,另一个cast()将值B设置为状态,然后两个状态都为空。设置值后,什么将保存到状态A、B或AB中@Brujo BenavidesYeah,正如您在我的代码中看到的,即使消息异步到达我们的服务器,循环一次只处理一个,并且每个回调的计算都是同步的(即,只有从
handle.*
返回某个内容,代码才会移动)。此外,非常明确地说,
gen_server:cast/2
不设置状态,它只向服务器进程发送一条消息。在我们的示例中,它看起来像
cast(Server,Msg)->Server!{cast,Msg}。
该消息在我们的
循环中被接收
,这就是计算
Mod:handle\u cast/2
的时候。
% 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