简体   繁体   English

Erlang / ets:在得到“坏参数”后重置ets表?

[英]Erlang/ets: reset ets table after getting a “bad argument”?

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,但有一件困扰我的事情是偶尔*, ets:match抛出一个bad argument ......而且,从它们开始,所有后续调用(甚至之前工作的调用)也抛出一个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? 有没有办法“重置” ets系统,以便我可以再次查询它(即从shell)?

*: I haven't been able to reproduce the problem… But it happens fairly often while I'm trying to do "other things". *:我无法重现这个问题......但是当我试图做“其他事情”时,它经常发生。

Although I'm not 100% sure, this thread seems to answer your question. 虽然我不是100%肯定,但这个主题似乎回答了你的问题。 It appears that you're observing this behaviour in the shell. 您似乎正在shell中观察此行为。 If so, two facts are interacting in a confusing way: 如果是这样,两个事实以令人困惑的方式相互作用:

  1. An ets table is deleted as soon as its owning process dies. 一旦其拥有进程终止,就会删除ets表。
  2. The erlang shell dies whenver it receives an exception and is silently restarted. 当erlang shell收到异常并以静默方式重新启动时,它将死掉。

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. 因此,当您获得第一个异常时,当前的shell进程将导致删除ets表,然后为您启动一个新的shell进程。 Now, when you try another ets:match , it fails because the table no longer exists. 现在,当您尝试另一个ets:match ,它会失败,因为该表不再存在。

Dale already told you what happens. 戴尔已经告诉过你会发生什么。 You can confirm that by calling self() in the shell every now and then. 您可以通过在shell中不时调用self()来确认。

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. 那个表不会随着你的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

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

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