Erlang/ets:在收到“错误参数”后重置 ets 表?

发布于 2024-08-15 20:25:58 字数 635 浏览 8 评论 0原文

我一直在学习如何使用 ets,但困扰我的一件事是,偶尔*,ets:match 会抛出一个错误的参数…而且,从他们开始,所有后续调用(甚至先前有效的调用)也会抛出错误参数:

> ets:match(Tid, { [$r | '$1'] }, 1).
% this match works...
% Then, at some point, this comes up:
** exception error: bad argument
     in function  ets:match/3
        called as ets:match(24589,{[114|'$1']},1)
% And from then on, matches stop working:
> ets:match(Tid, { [$r | '$1'] }, 1).
** exception error: bad argument
     in function  ets:match/3
        called as ets:match(24589,{[114|'$1']},1)

是否有任何方法可以“重置”ets 系统以便我可以查询它(即,来自外壳)再次?

*:我无法重现这个问题……但是当我尝试做“其他事情”时,这种情况经常发生。

I've been learning how to use ets, but one thing that has bothered me is that, occasionally*, ets:match throws a bad argument… And, from them on, all subsequent calls (even calls which previously worked) also throw a bad argument:

> ets:match(Tid, { [$r | '$1'] }, 1).
% this match works...
% Then, at some point, this comes up:
** exception error: bad argument
     in function  ets:match/3
        called as ets:match(24589,{[114|'$1']},1)
% And from then on, matches stop working:
> ets:match(Tid, { [$r | '$1'] }, 1).
** exception error: bad argument
     in function  ets:match/3
        called as ets:match(24589,{[114|'$1']},1)

Is there any way to "reset" the ets system so that I can query it (ie, from the shell) again?

*: I haven't been able to reproduce the problem… But it happens fairly often while I'm trying to do "other things".

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

是你 2024-08-22 20:25:58

虽然我不是 100% 确定,此帖子似乎回答了你的问题。您似乎正在 shell 中观察到这种行为。如果是这样,则两个事实以令人困惑的方式相互作用:

  1. ets 表在其所属进程终止后立即被删除。
  2. 当 erlang shell 收到异常时,它就会终止并以静默方式重新启动。

因此,当您收到第一个异常时,当前 shell 进程会终止,导致 ets 表被删除,然后会为您启动一个新的 shell 进程。现在,当您尝试另一个 ets:match 时,它会失败,因为该表不再存在。

Although I'm not 100% sure, this thread seems to answer your question. It appears that you're observing this behaviour in the shell. If so, two facts are interacting in a confusing way:

  1. An ets table is deleted as soon as its owning process dies.
  2. The erlang shell dies whenver it receives an exception and is silently restarted.

So, when you get the first exception, the current shell process dies causing the ets table to be deleted, and then a new shell process is started for you. Now, when you try another ets:match, it fails because the table no longer exists.

雨的味道风的声音 2024-08-22 20:25:58

戴尔已经告诉过你会发生什么。您可以通过在 shell 中不时调用 self() 来确认这一点。

作为一种快速解决方法,您可以生成另一个进程来为您创建公共表。那么那张桌子就不会和你的外壳一起死掉了。

1> self().
<0.32.0>    % shell's Pid

2> spawn(fun() -> ets:new(my_table, [named_table, public]), receive X -> ok end end).
<0.35.0>    % the spawned process's Pid

3> ets:insert(my_table, {a, b}).
true

现在破例并检查该表是否确实幸存下来。

4> 1/0.
** exception error: bad argument in an arithmetic expression
     in operator  '/'/2
        called as 1 / 0
5> self().
<0.38.0>   % shell's reborn, with a different Pid

6> ets:insert(my_table, {c, d}).
true
7> ets:tab2list(my_table).
[{c,d},{a,b}]    % table did survive the shell restart

要删除该表,只需向您生成的进程发送一些内容:

8> pid(0,35,0) ! bye_bye.
bye_bye
9> ets:info(my_table).   
undefined

Dale already told you what happens. You can confirm that by calling self() in the shell every now and then.

As a quick workaround you can spawn another process to create a public table for you. Then that table won't die along with your shell.

1> self().
<0.32.0>    % shell's Pid

2> spawn(fun() -> ets:new(my_table, [named_table, public]), receive X -> ok end end).
<0.35.0>    % the spawned process's Pid

3> ets:insert(my_table, {a, b}).
true

Now make an exception and check that the table indeed survived.

4> 1/0.
** exception error: bad argument in an arithmetic expression
     in operator  '/'/2
        called as 1 / 0
5> self().
<0.38.0>   % shell's reborn, with a different Pid

6> ets:insert(my_table, {c, d}).
true
7> ets:tab2list(my_table).
[{c,d},{a,b}]    % table did survive the shell restart

To delete the table, just send something to your spawned process:

8> pid(0,35,0) ! bye_bye.
bye_bye
9> ets:info(my_table).   
undefined
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文