带有和没有外壳的ET的不同行为

  • 本文关键字:ET 外壳 erlang ets
  • 更新时间 :
  • 英文 :


首先我正在学习Erlang。根本不是专家。在使用ET进行一些示例时,我遇到了我不了解的东西(即使在搜索之后)。

我有一个用

创建公共ET的过程
TableID = ets:new(tablename, [public])}

i然后将表格传递给其他过程。当我这样做时,运行模块会形成外壳,一切都可以。当我使用erl -noshell -s ...甚至没有-noshell选项的完全相同的模块时,它会失败。我不断出现错误:badarg好像不存在表。ID正确通过,但桌子实际上表现为私人!

从外壳或没有?

的交互模块之间有区别

谢谢


我正在添加我用来尝试调试问题的代码的示例。由于它是一个较大的软件(并且基本上被剥离到骨头以找到问题),因此可能很难理解。

-record(loop_state, {
        commands
        }).
start() ->
    LoopState = #loop_state{commands = ets:new(commands, [public])},
    tcpserver_otp_backend:start(?MODULE, 7000, {?MODULE, loop}, LoopState).
loop(Socket, LoopState = #loop_state{commands = Commands}) ->
    case gen_tcp:recv(Socket, 0) of
        {ok, Data} ->
            % the call below fails, no error generated, AND only in non interactive shell
            A = newCommand(Commands, Data), 
            gen_tcp:send(Socket, A),
            loop(Socket, LoopState);
        {error, closed} ->
            ok
    end.

 newCommand(CommandTableId, Command) ->
    case ets:lookup(CommandTableId,Command) of 
        [] ->
            _A = ets:insert(CommandTableId, {Command, 1}),
            <<1, "new", "1">>; % used for testing
        _ ->
            <<1, "old", "1">> % used for testing
    end.

当我删除"犯罪命令" ETS:查找时,所有这些都可以作为int互动壳。

问题似乎是您在start()函数中创建了ETS表。ETS表有一个所有者(默认情况下,创建过程),当所有者死亡时,该表被删除。当您通过将-s传递到ERL从命令行运行启动/0函数时,该所有者进程将是ERLANG内核中的某个内部进程,它是处理启动序列的一部分。不管您是否通过-noshell,该过程可能是短暂的,并且在查找功能有时间执行之前会死亡,因此当查找最终发生时,该表不再存在。

创建ETS表的合适位置将在您启动的Gen_Server的init()回调函数中。如果应该是通过多个进程访问的公共est表,那么您可能需要创建一个单独的服务器进程,其任务是拥有该表。

相关内容

  • 没有找到相关文章

最新更新