繁体   English   中英

Erlang ETS插入/ 2错误

[英]Erlang ETS insert/2 error

我试图通过访问ETS模块创建一个简单的Erlang进程。

我的源代码包括:

  1. 流程创建:

     start_message_channel() -> Table = ets:new(messages, [ordered_set, named_table]), Channel = spawn(?MODULE, channel, []), {Channel, {table, Table}}. 
  2. 流程逻辑:

     channel() -> receive {Sender, {send_message, {Message, Table}}} -> ets:insert(Table, {message, Message}), Sender ! {self(), {status, success}}; {Sender, {receive_message, Table}} -> {message, Message} = ets:first(Table), Sender ! {self(), {status, {success, Message}}}; _ -> throw(incorrect_protocol_exception) end. 
  3. 与流程沟通

     send_message_to_message_channel({Channel, {table, Table}}, Message) -> Channel ! {self(), {send_message, {Message, Table}}}, receive {Channel, {status, success}} -> io:format("Message sent!~n"); {Channel, {status, failure}} -> io:format("Message failed to send!~n"); _ -> throw(incorrect_protocol_exception) end. receive_message_from_message_channel({Channel, {table, Table}}) -> Channel ! {self(), {receive_message, Table}}, receive {Channel, {status, {success, Message}}} -> io:format(Message); {Channel, {status, failure}} -> io:format("Message failed to receive!~n"); _ -> throw(incorrect_protocol_exception) end. 

在Erlang终端中执行函数调用时,我收到错误:

    1> cd("C:/Users/dauma").                    
    C:/Users/dauma
    ok
    2> c(message_channel).
    {ok,message_channel}
    3> Object = message_channel:start_message_channel().
    {<0.59.0>,{table,messages}}
    4> message_channel:send_message_to_message_channel(Object, "Hello World!").

    =ERROR REPORT==== 19-May-2016::11:09:27 ===
    Error in process <0.59.0> with exit value:
    {badarg,[{ets,insert,[messages,"Hello World!"],[]},
        {message_channel,channel,0,
            [{file,"message_channel.erl"},{line,35}]}]}

谁能告诉我,问题可能出在哪里?

ETS表由Erlang进程拥有,并具有访问控制。 默认情况下,表是protected ,只能由拥有它的进程写入,尽管可以从其他进程读取。

如果要从其他进程读取和写入,请使用public

Table = ets:new(messages, [ordered_set, named_table, public])

您也可以使用private ,这意味着只有拥有进程才能读写。

根据文件

  • public任何进程都可以读取或写入表。
  • protected所有者进程可以读取和写入表。 其他进程只能读取表。 这是访问权限的默认设置。
  • private只有所有者进程可以读取或写入表。

在您的示例中,您在一个进程中创建表(一个调用start_message_channel ),然后您尝试调用ets:insert从另一个进程ets:insertspawn(?MODULE, channel, [])创建一个新进程, channel为它的切入点。

由于您的表未标记为public ,因此对其他进程的ets:insert的调用将失败并显示badarg

根据文档,再次

通常,如果任何参数的格式错误,表标识符无效或者由于表访问权限( protectedprivate )而拒绝操作,则下面的函数将以badarg原因退出。


附注:如果使用named_table ,则从ets:new返回的值表名,因此您可以这样做:

-define(TABLE, messages).

% later...
?TABLE = ets:new(?TABLE, [named_table, ordered_set, protected])

...而且您不需要将返回的值存储在状态中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM