正如您可能知道的,gen_tcp有三种模式。{active, false}、{active, true}和{active, once}。
我已经阅读了一些关于{active, false}、{active, true}和{active, once}的文档。然而,我没有得到它。
{active, false}与{active, true}和{active, once}之间的区别是什么
你能清楚地解释一下吗?
发布于 2018-07-17 16:43:23
它是关于流控制的:您有一个处理传入网络流量的Erlang进程。通常,您希望它对传入的数据包做出快速反应,但您不希望它的消息队列增长速度超过其处理速度-但在某些情况下,您会有不同的目标。
使用{active, false},您可以显式控制进程何时接收传入流量:只有在您调用gen_tcp:recv时才会发生。但是,当进程在gen_tcp:recv中等待时,它不能接收其他Erlang消息。也许其他某个Erlang进程正在发送一条消息,告诉它停止,但它还不知道,因为它正专注于获取网络输入。
使用{active, true},一旦网络输入可用,就会将其作为消息发送到进程。这意味着您可以拥有一个receive表达式,该表达式期望来自其他进程的网络流量和简单的Erlang消息。如果您确信您的流程可以在输入到达之前更快地处理它,那么这种操作模式可能会很有用,但您最终可能会得到一个永远不会被清除的长消息队列。
{active, once}是两者之间的折衷方案:您以Erlang消息的形式接收传入数据,这意味着您可以将网络流量与其他工作混合在一起,但是在接收到数据包之后,您需要再次显式地使用{active, once}调用inet:setopts来接收更多数据,因此您可以决定进程接收消息的速度。
自Erlang/OTP17.0以来,还有另一个选项{active, N},其中N是整数。这意味着您可以在再次调用inet:setopts之前接收N消息。这可以在不放弃流量控制的情况下提供更高的吞吐量。
发布于 2018-07-17 01:07:24
{active,false}
您必须通过调用gen_tcp:recv()从套接字读取数据块。
{active,true}
Erlang自动从套接字读取数据块,并将这些数据块收集成一条完整的消息,然后将该消息放入进程邮箱。您可以使用receive子句读取消息。如果某个怀有敌意的参与者向您的邮箱发送大量消息,您的进程将崩溃。
{active,once}
对于从套接字读取的第一个数据块,相当于{active, true},然后对于任何后续数据块,则相当于{active, false}。
您还需要了解指定{packet, N}是如何影响事情的。请看这里:Erlang gen_tcp not receiving anything。
https://stackoverflow.com/questions/51364148
复制相似问题