{active,false},{active,true}和{active,一旦一次}有什么区别?

时间:2018-07-16 14:28:58

标签: networking tcp erlang elixir gen-tcp

您可能知道的

,有gen_tcp的三种模式。 {active, false}{active, true}{active, once}

我已经阅读了有关{active, false}{active, true}{active, once}的一些文档。但是,我没有得到。

{active, false}{active, true}{active, once}有什么区别?

能请您解释清楚吗?

2 个答案:

答案 0 :(得分:3)

{有效,错误}
您必须通过调用gen_tcp:recv()从套接字读取大量数据。

{有效,真实}
Erlang会自动为您从套接字读取数据块,并将这些块收集为完整的消息,并将该消息放入进程邮箱中。您使用receive子句阅读消息。如果某个敌对的演员充斥着邮件,您的邮箱将崩溃。

{活动一次}
从套接字读取的第一批数据等效于{active, true},对于随后的所有数据等效于{active, false}

您还需要了解指定{packet, N}如何影响事物。参见此处:Erlang gen_tcp not receiving anything

答案 1 :(得分:3)

这与流量控制有关:您有一个Erlang进程来处理传入的网络流量。通常,您希望它对传入的数据包做出快速反应,但又不希望它的消息队列增长得​​快于它可以处理的速度-但在某些情况下,您会有不同的目标。

使用{active, false},您可以明确控制进程何时接收传入流量:仅在调用gen_tcp:recv时发生。但是,当进程在gen_tcp:recv中等待时,它无法接收其他Erlang消息。也许其他的Erlang进程正在发送一条消息,告诉它停止运行,但是它尚不知道,因为它专注于获取网络输入。

使用{active, true},网络输入将在可用时作为消息发送到进程。这意味着您可能有一个receive表达式,该表达式期望网络流量和来自其他进程的简单Erlang消息。如果您确信自己的进程可以比输入更快地处理输入,但是这种操作模式可能很有用,但是最终可能会得到一个长消息队列,并且永远不会清除。

{active, once}是两者之间的折衷:您以Erlang消息的形式接收传入数据,这意味着您可以将网络流量与其他工作混合使用,但是在收到数据包后,您需要显式调用inet:setopts再次{active, once}接收更多数据,因此您可以决定进程接收消息的速度。

自Erlang / OTP 17.0起,还有另一个选择{active, N},其中N是整数。这意味着您可以先收到N条消息,而不必再次致电inet:setopts。这样可以提高吞吐量,而不必放弃流控制。