我想知道是否可以将变量从死亡过程发送到它的调用过程。我有一个进程A通过spawn_link生成另一个进程B.通过调用exit(已杀死)即将死亡。我可以在A中通过{'EXIT',From,killed}来捕获它,但是我想在它死之前将一些变量从B传递给A.我可以通过在B到A之前向B发送消息来做到这一点,但我想知道这是否是一件“坏事”。因为从技术上来说,我会发送两条从B到A的消息。现在,我看起来像这样:
B sends a message with values to A
A receives values and re-enters receive loop
B calls exit(killed)
A receives EXIT message and spawns another linked process
这个想法是B应该永远存在,当它被杀死时,它应该立即“复活”。在我看来,似乎更好的替代方案是使用exit(已杀死,[变量])并使用{'EXIT',From,killed,[Variables]}来捕获它。这可能吗?如果是这样,有没有理由不这样做?当B甚至没有死亡时,拥有B的商店价值似乎是一个糟糕的举动。我必须开始实施原子操作,以防止两个链接进程同时出现问题。它还迫使我将变量保存在我的接收循环中。
我的意思是,如果我可以直接使用EXIT调用发送值,我的循环将如下所示:
loop() ->
receive ->
{'EXIT', From, killed, Variables} -> % spawn new linked process with variables
end.
但是,如果我首先需要收到一条消息,再次进入循环然后接收退出消息,我会得到;
loop(Vars) ->
receive ->
{values, Variables} -> loop(Variables);
{'EXIT', From, killed} -> % spawn new linked process with variables
end.
这意味着在我不再需要它之后我会保留变量列表,并且我需要两次输入我的循环才能被认为是一个动作。
答案 0 :(得分:4)
直接回答您的问题:退出原因可以是任何术语,这意味着它也可以是exit({killed, Values})
之类的元组,因此您不会接收{'EXIT', From, killed, Values}
已收到{'EXIT', From, {killed, Values}}
。
但是!
你现在的做法不是错误。它也不是特别难看。发送消息(尤其是异步消息)不是要尽可能最小化的一些主要操作,也不是产生/终止进程。如果你的方式适合你,那很好。
但是! (再次!)强>
你为什么要这样做呢?考虑一下状态是什么,你需要在两个进程之间穿梭,其中一个你刚刚终止?该值是否应该是产卵过程持有的永久实体?应该和工人一起死吗?它是否应该是由第三个过程维护的数量,并被要求作为工人创业的一部分(更广泛地说明ŁukaszPtaszyński所得到的)?
我不知道这些问题的答案,因为我不了解你的程序,但如果我发现有必要做这类工作,那就是我想到的事情。特别是,如果有一些基本值,进程A必须使进程B为其工作,并且基本值的下一个版本依赖于进程B所做的事情,那么进程B应该将其返回为部分处理,而不是其关闭的一部分。
这似乎是一个小的语义差异,但重要的是要考虑。您可能会发现您根本不应该终止B,或者您确实需要A来管理多个并发B的目录,并且它们应该在它们移动时播种,或者其他什么。您甚至可能会发现这意味着A应该将B生成为同步的受监视操作,而不是异步链接操作,并且整个进程群应该作为多个托管A-B对的复合体生成!我不知道你的答案,但这些是你在阅读你正在做的事情时想到的事情。
答案 1 :(得分:0)
我认为你可以尝试这种方法:
main()->
ParentPid = self(),
From = spawn_link(?MODULE, child, [ParentPid]),
receive
{'EXIT', From, Reason} ->
Reason
end.
child(ParentPid) ->
Value = 2*2,
exit(ParentPid, {killed, Value}).
请阅读此关于erlang:exit/2
的链接