在 Erlang 中,消息的发送者通常在发送消息后立即忘记它并继续其工作。如果应用程序需要确认消息接收,您必须构建自己的协议(或使用现有协议)。有很多很好的理由。
一是大多数时候没有必要握手。消息被忽略的更高风险是接收进程不再存在,或者同时死亡,在这种情况下,发送者几乎没有机会做一些有趣的事情。
此外,握手是一种阻塞动作,因此会影响性能,并存在死锁的风险。
确认也应该是一条消息,但不应确认这条消息,否则您将创建一个永无止境的消息循环。只有应用程序才能知道要做什么(例如使用带有确认的发送),并且编写这种函数(或使用实现它的行为)真的很容易。例如:
send_with_ack(To,Mess,TimeOut,Ack) ->
Ref = make_ref(),
To ! {Mess,self(),Ref},
receive
{Ack,Ref} -> Ack
after Timeout ->
{error,timeout}
end.
receiving_process() ->
...
receive
{Pattern_matching_Mess,From,Ref} ->
do_something(),
From ! {Ack,Ref}, %% Ack for this kind of message is known by the receiver
do_somethingelse();
Mess1 -> do_otherthing()
end,
...
只需很少的工作,甚至可以将消息传递的调查委托给一个新进程 - 不阻塞检查 - 并使用链接进程,如果达到超时,则强制发送方崩溃。