Erlang Thursday - ETS介绍第一篇

今天的Erlang Thursday开始介绍 ets 模块以及ETS的概况。

ETS是 Erlang Term Storage的缩写,是Erlang term(各种Erlang数据类型)的内存存储,它提供对存储的数据恒定的访问时间。

ETS可以被认为是一种键值对存储类型的存储,并且它用表的概念来组织数据。

第一个很有用的知识点是,ETS表是被一个进程创建的,这个表的创建者就是这个表的所有者,除非它把表转移给别的进程。

一旦所有者进程死掉,这个表也就被删除,而且再也不能被访问。

让我们看一下这会是什么样子。

首先,在启动了一个新的Erlang shell后,我们先看看我们所在shell的PID(进程标识符)。

1
2
self().
% <0.34.0>

接着创建一个新的ETS表。我们在以后的文章里会专门详细介绍各种创建新表的方式,而今天我们只是仅仅指定一个名字和一个空的参数列表来创建一个新表。

1
2
TableId = ets:new(table, []).
% 20496

获得表的id后,我们用 ets:info/1 函数来看看表的信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ets:info(TableId).
% [{read_concurrency,false},
% {write_concurrency,false},
% {compressed,false},
% {memory,305},
% {owner,<0.34.0>},
% {heir,none},
% {name,table},
% {size,0},
% {node,nonode@nohost},
% {named_table,false},
% {type,set},
% {keypos,1},
% {protection,protected}]

是时候来让所有者进程崩溃了。在这个场景,我们用一个错误的模式匹配来引起一个错误匹配异常。

1
2
1 = 2.
% ** exception error: no match of right hand side value 2

现在我们检查PID变量和当前shell的进程是否匹配来证实Erlang真的启动了一个新的shell进程让我们使用。

1
2
self().
% <0.40.0>

很明显,当前的shell的PID和我们第一次调用self()获得的PID不一样。

再来看看我们刚才创建的表的信息。

1
2
ets:info(TableId).
% undefined

结果是 undefined 。因此我们再也找不到那个表id所指的表了。

接下来我们用 ets:all/0 是否能看到虽然用 ets:info/1 找不到的表在某个地方藏着呢。

1
2
3
4
5
ets:all().
% [8207,file_io_servers,inet_hosts_file_byaddr,
% inet_hosts_file_byname,inet_hosts_byaddr,inet_hosts_byname,
% inet_cache,inet_db,global_pid_ids,global_pid_names,
% global_names_ext,global_names,global_locks,4098,1,ac_tab]

还是没找到。让我们用和前面同样的名字创建另外一个表。

1
2
Table2Id = ets:new(table, []).
% 24592

创建成功而且没有报这个名字已经存在的错误。

我们再用 ets:all/0 来看看,这回能看到刚才 ets:new/2 返回的id。

1
2
3
4
5
ets:all().
% [24592,8207,file_io_servers,inet_hosts_file_byaddr,
% inet_hosts_file_byname,inet_hosts_byaddr,inet_hosts_byname,
% inet_cache,inet_db,global_pid_ids,global_pid_names,
% global_names_ext,global_names,global_locks,4098,1,ac_tab]

我们再让shell崩溃一次。

1
2
1 = 2.
% ** exception error: no match of right hand side value 2

我们注意到我们又有了新的shell进程。

1
2
self().
% <0.47.0>

如果我们再调用 ets:all/0 ,前面我们刚刚创建的表的id又没有了。

1
2
3
4
5
ets:all().
% [8207,file_io_servers,inet_hosts_file_byaddr,
% inet_hosts_file_byname,inet_hosts_byaddr,inet_hosts_byname,
% inet_cache,inet_db,global_pid_ids,global_pid_names,
% global_names_ext,global_names,global_locks,4098,1,ac_tab]

上述就是我们对ETS的初始印象,我们演示了所有者进程崩溃会删除表,我们也预览了ets模块的一些函数,特别是 ets:new/2 ,ets:info/1 和 ets:all/0 。

我们将继续在后面几篇文章里浏览ETS,并且在大概预览一些ets模块的函数后,我们会深入研究ets模块里与众不同的函数。

原文链接: https://www.proctor-it.com/erlang-thursday-ets-introduction-part-1/