我如何改变Erlang VM使用一个随机的128位值为它的pid值之一?
目前我能设置的最大值是:
32> pid(1, 32767, 8191).
** exception error: bad argument
in function list_to_pid/1
called as list_to_pid("<1.32767.8191>")
in call from c:pid/3 (c.erl, line 419)
33> pid(0, 32767, 8191).
<0.32767.8191>
看起来pid的生成在erts/emulator/beam/erl_ptab.h:283
中是这样的:
ERTS_GLB_INLINE Eterm
erts_ptab_make_id(ErtsPTab *ptab, Eterm data, Eterm tag)
{
HUint huint;
Uint32 low_data = (Uint32) data;
low_data &= (1 << ERTS_PTAB_ID_DATA_SIZE) - 1;
low_data <<= ERTS_PTAB_ID_DATA_SHIFT;
huint.hval[ERTS_HUINT_HVAL_HIGH] = erts_ptab_data2pix(ptab, data);
huint.hval[ERTS_HUINT_HVAL_LOW] = low_data | ((Uint32) tag);
return (Eterm) huint.val;
}
你为什么要这样做?创建一个pid并不能保证有一个进程使用该pid,或者永远有一个进程使用该pid,只有从spawn
返回才能确保这一点。有人能解释一下Erlang中Pid的结构吗?获取不同字段含义的解释。这将有助于解释为什么不能将其设置为任意值。
在启动erlang时,可以通过'+ p Number'选项设置进程表的大小。这将给出第二个字段的最大值。
EDIT:就这个问题和下面的评论再做一些评论。
注意,pid,进程标识符,只是一个对进程的引用,而不是进程本身。当你spawn
一个进程,你得到一个新的进程和一个新的pid引用它。当您在shell中使用pid/3
或使用list_to_pid/1
创建pid时,您得到的只是一个pid,它可能引用或不引用进程。
现在在BEAM中没有办法控制创建进程时得到哪个pid。如果您确实需要此功能,则必须在内部修改BEAM以实现此功能。考虑到BEAM是内部结构化的(带有一个进程表),以及pid是如何结构化的,这可能非常困难。例如,pid中的一个字段是进程在进程表中的索引,所以不同的pid具有相同的表索引是非法的。
不是一个更好的解决方案,而不是创建一个标识符/pid表?