4

Erlang で ets:select を使用すると奇妙な動作が発生します。

正しい select ステートメント (下の 4 と 5) を達成した後、ステートメントでエラーを犯し (下の 6)、4 と 5 と同じステートメントを再試行しましたが、機能しなくなりました。

何が起こっている ?何か案が ?

Erlang R14B01 (erts-5.8.2) [source] [smp:2:2] [rq:2] [async-threads:0] [kernel-poll:false]

Eshell V5.8.2  (abort with ^G)
1> Tab = ets:new(x, [private]).
16400
2> ets:insert(Tab, {c, "rhino"}).
true
3> ets:insert(Tab, {a, "lion"}). 
true
4> ets:select(Tab,[{{'$1','$2'},[],['$1', '$2']}]).      
["rhino","lion"]    
5> ets:select(Tab,[{{'$1','$2'},[],['$1', '$2']}]).      
["rhino","lion"]
6> ets:select(Tab,[{{'$1','$2'},[],['$1', '$2', '$3']}]).
** exception error: bad argument
 in function  ets:select/2
    called as ets:select(16400,[{{'$1','$2'},[],['$1','$2','$3']}])
7> ets:select(Tab,[{{'$1','$2'},[],['$1', '$2']}]).      
** exception error: bad argument
 in function  ets:select/2
    called as ets:select(16400,[{{'$1','$2'},[],['$1','$2']}])

私のetsテーブルは破壊されましたか?それはetsのバグでしょうか?

ありがとうございました。

4

2 に答える 2

6

シェル プロセスは ETS テーブルを作成し、その所有者です。所有者プロセスが終了すると、ETS テーブルは自動的に削除されます。

そのため、で例外が発生する6と、シェル プロセスが終了し、ETS テーブルが削除されます。

これを作成すると、他のプロセスがそれにアクセスできないことprivateも意味します (そのため、テーブルが永続化されていたとしても、新しいシェルはそれにアクセスできなくなります) が、この場合、テーブルが削除されているため、さらに悪化します。

于 2012-10-27T15:35:33.580 に答える
3

(thanosQRの正解にコメントとして残すには大きすぎます)

シェルで例外が発生してもテーブルを存続させたい場合は、テーブルを別のプロセスに渡すことができます。例えば:

1> Pid = spawn(fun () -> receive foo -> ok end end).    % sit and wait for 'foo' message
<0.62.0>
2> Tab = ets:new(x, [public]).                          % Tab must be public if you plan to give it away and still have access
24593
3> ets:give_away(Tab, Pid, []).
true
4> ets:insert(Tab, {a,1}).
true
5> ets:tab2list(Tab).
[{a,1}]
6> 3=4.
** exception error: no match of right hand side value 4
7> ets:tab2list(Tab).                                   % Tab survives exception
[{a,1}]
8> Pid ! foo.                                           % cause owning process to exit
foo
9> ets:tab2list(Tab).                                   % Tab is now gone
** exception error: bad argument
     in function  ets:match_object/2
        called as ets:match_object(24593,'_')
     in call from ets:tab2list/1 (ets.erl, line 323)
于 2012-10-27T21:45:31.843 に答える