c—修改Erlang虚拟机的Pid



我如何改变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表?

相关内容

  • 没有找到相关文章

最新更新