(1)进程死后,是否有可能将其pid重新分配给由spawn()?创建的另一个进程?
(2)如果是,那么通信安全如何?例如,向Pid邮件的发件人发送回复.如果发件人已崩溃,我们怎么知道这Pid不属于另一个进程呢?
(3) pid重用有什么保证?例如,在重用pid之前是否有最小间隔?
(4)通常采取哪些措施来防止因重复使用pid而导致的错误?它被忽略了吗?
很多问题......
一方面没有详尽无遗,另一方面又过于迂回,我们考虑一个实际的例子:OTP功能gen_server:call/2,3.
当您使用gen_server:call/2,3gen_server模块时,生成一个组合的消息标记,{self(), make_ref()}除了监视正在发送消息的进程外,还看起来像.发送过程保证至少如果它正在调用的进程在发送回复之前死亡,将接收监视器退出消息而不是响应,并且死亡进程的PID将与它刚刚调用的PID匹配.被接收消息的接收处理将被接收发送方的PID 和被保证是本地唯一一个Erlang参考(至少对于相当长的时间-相信独特的空间中的某处十亿) .当它发送响应时,接收过程也必须知道该引用,并且由最初用于发送的PID寻址.
这是可能的(虽然非常不可能),其发送过程中可能已经死了,一个新的进程可能已经重生具有相同PID,但它是非常接近不可能用相同的PID催生另一个进程,并会阻止在gen_server:call/2,3恰好具有与旧的死调用相同的内部运行时引用的消息.
除了这种几乎不可能之外,让我们考虑一个世界,这个世界真的发生了奇怪的事情,所有的保护措施都失败了......
(大约2^64 * 2^64 * chance_of_failure_on_this_tiny_scale())
发送过程会得到一个奇怪的响应消息,几乎肯定会失败一个断言匹配并在下一行死掉,并在已知状态下重启.两次发生同样问题的可能性可能低于接下来几分钟内质子衰减的几率.
这是"正确性"吗?没有.在大规模并发系统中没有可证明的正确性.这就像试图"证明"代表全人类的单一方程式.大多数Erlang系统本质上都是混乱的,因此通常无法证明系统.您可以证明的是,单个纯函数是正确的,并且副作用过程在其生命周期中可能调用的所有函数都具有明确的终止条件,包括崩溃对不稳定的数据.最后一部分是Erlang如何实现如系统的强大稳健性(良好的编码实践,遵守功能原则以及使用Dialyzer的强大文化也有很大帮助).
所以......"正确性"......尽可能多地证明功能.这是一件好事,为什么我们有像PropER和QuickCheck这样的工具.作为一套通用指南,请尽力写下:
=.这就是为什么Erlang =是一体化的赋值,断言和统一的原因.除非你在学术界(这个功能可能会在下面调用一个巨大的世界,所以这并不是一个很大的限制),以比功能更大的比例进行校对是一个愚蠢的错误.针对不可能或锁定条件的校对协议也是可能的,如果你有时间,那就去吧(否则做我们其他人做的事情,并坚持超时和返工过去实际上超时的代码) - 这不应该是经常发生的事情).
所有这一切...... Steve-O几乎肯定会在数据中心的数据线上绊倒并在接下来的两年内将群集拆分多次,而不是任何人看到PID环绕导致实际的冲突.下一个十年.
| 归档时间: |
|
| 查看次数: |
320 次 |
| 最近记录: |