8

私は ets の使い方を学んでいますが、私を悩ませていることの 1 つは、ときどき*、 … をets:matchスローすることbad argumentです。そして、それ以降、後続のすべての呼び出し (以前は機能していた呼び出しも含む) も : をスローしbad argumentます。

> ets:match(Tid, { [$r | '$1'] }, 1).
% このマッチは機能します...
% その後、ある時点で、これが表示されます。
** 例外エラー: 引数が正しくありません
     関数 ets:match/3 で
        ets:match(24589,{[114|'$1']},1) として呼び出されます
% それ以降、マッチは機能しなくなります:
> ets:match(Tid, { [$r | '$1'] }, 1).
** 例外エラー: 引数が正しくありません
     関数 ets:match/3 で
        ets:match(24589,{[114|'$1']},1) として呼び出されます

システムを「リセット」して、ets(つまり、シェルから) 再度クエリできるようにする方法はありますか?

*: 問題を再現することはできませんでしたが、「他のこと」をしようとしているときにかなり頻繁に発生します。

4

2 に答える 2

15

100% 確信はありませんが、このスレッドはあなたの質問に答えているようです。シェルでこの動作を観察しているようです。もしそうなら、2 つの事実が紛らわしい方法で相互作用しています。

  1. ets テーブルは、所有しているプロセスが終了するとすぐに削除されます。
  2. erlang シェルは、例外を受け取るたびに終了し、サイレントに再起動されます。

そのため、最初の例外が発生すると、現在のシェル プロセスが終了して ets テーブルが削除され、新しいシェル プロセスが開始されます。ここで、別の を試すとets:match、テーブルが存在しないために失敗します。

于 2009-12-27T03:47:39.750 に答える
3

デールはすでに何が起こるかをあなたに話しました。シェルで 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
于 2009-12-27T09:14:15.747 に答える