【问题标题】:What is difference between {active, false}, {active, true} and {active, once}?{active, false}, {active, true} 和 {active, once} 有什么区别?
【发布时间】:2018-12-24 03:19:23
【问题描述】:

您可能知道,gen_tcp 有三种模式。 {active, false}{active, true}{active, once}

我已经阅读了一些关于{active, false}{active, true}{active, once} 的文档。但是,我没听懂。

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

你能解释清楚吗?

【问题讨论】:

标签: networking tcp erlang elixir gen-tcp


【解决方案1】:

这是关于流量控制的:你有一个 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 是整数。这意味着您可以在再次拨打inet:setopts 之前收到N 消息。这可以提供更高的吞吐量,而不必放弃流量控制。

【讨论】:

    【解决方案2】:

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

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

    {有效,一次}
    从套接字读取的第一个数据块相当于{active, true},然后是任何后续数据块的{active, false}

    您还需要了解指定{packet, N} 是如何影响事物的。见这里:Erlang gen_tcp not receiving anything

    【讨论】:

      猜你喜欢
      • 2010-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-28
      • 2013-08-30
      • 2013-04-19
      • 2011-10-02
      • 2013-06-07
      相关资源
      最近更新 更多