试图找到有关详细信息的文档,我找不到更多内容:
对我来说,这留下了许多不清楚的事情。
原子字值是否始终相同,与序列模块加载到运行时实例无关?如果模块A和B都定义/引用了一些原子,那么原子的值会在会话之间变化,这取决于是先加载A还是B?
当匹配模块内的原子时,是否有一些"原子文字到原子值"决议发生了?模块是否有一些自己的模块本地原子值查找表,它在模块的加载时填充?
在2个erlang运行时实例相互通信的分布式场景中。是否有一些" sync-atom-tables"行动还在继续?或者将原子序列化为字符串文字,而不是单词?
答案 0 :(得分:9)
Atom只是VM维护的ID。 ID的表示是底层体系结构的机器整数,例如, 32位系统上4个字节,64位系统上8个字节。请参阅LYSE book。
中的用法同一个正在运行的VM中的同一个原子始终映射到相同的ID(整数)。例如,以下元组:
{apple, pear, cherry, apple}
可以作为以下元组存储在实际的Erlang内存中:
{1, 2, 3, 1}
所有原子都存储在一个永远不会被垃圾收集的大表中,即一旦在正在运行的VM中创建一个原子,它就会停留在表中,直到VM关闭为止。
回答你的问题:
1。否。原子的ID将在VM运行之间发生变化。如果关闭VM并重新加载元组,系统可能最终会得到以下ID:
{50, 51, 52, 50}
取决于在加载之前已创建的其他原子。原子只与VM一样长。
2. 否。每个VM只有一个原子表。加载模块时,模块中的所有文字原子都映射到它们的ID。如果该表中尚不存在特定原子,则将其插入并保持不变直到VM重新启动。
3。否。具有原子的表是每个VM,它们是分开的。考虑两个VM同时启动但彼此不了解的情况。在每个VM中创建的原子可能在表中具有不同的ID。如果在某个时间点,一个节点了解另一个节点,则不同的原子将具有不同的ID。它们不容易同步或合并。但原子不仅仅是作为文本表示发送到另一个节点。它们被“压缩”为一种缓存形式,并在标题中一起发送。请参阅通信协议说明中的distribution header。基本上,标题包含稍后使用的原子及其ID和文本表示。然后每个术语通过标题中指定的ID引用atom,而不是每次都传递相同的文本。
答案 1 :(得分:0)
在不进行实施的情况下获得真正的基础。原子是一个文字的东西"有一个名字。它的价值始终是它自己而且它知道自己的名字。您通常在需要标记时使用它,例如原子ok
和error
。原子是唯一的,因为系统中只有一个原子foo
,每次我引用foo
我指的是同一个foo
,不管它们是否在相同的模块,或者它们是否来自同一个过程。总是只有一个foo
。
一点实施。所以原子存储在一个全局原子表中,当你创建一个新的原子时,它就会被插入到表中,如果它还没有存在的话。这使得比较原子的相等性非常快,因为您只需检查两个原子是否引用原子表中的相同槽。
虽然VM的单独实例节点具有单独的原子表,但是分布式erlang中的节点之间的通信已针对此进行了优化,因此您通常不需要发送实际原子节点之间的名称。