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

use*_*809 1 erlang networking tcp elixir gen-tcp

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

我已经阅读了一些关于{active, false},{active, true}和 的文件{active, once}。然而,我没有得到它。

{active, false}{active, true}和 和有什么不一样{active, once}

能不能简单解释一下?

7st*_*tud 6

{active, false}
您必须通过调用 gen_tcp:recv() 从套接字读取一块数据。

{active, true}
Erlang 自动从套接字读取数据块,并将这些数据块收集成完整的消息,并将消息放入进程邮箱中。您使用子句阅读消息receive。如果某些敌对行为者用邮件淹没您的邮箱,您的进程将崩溃。

{active, Once}
相当于{active, true}从套接字读取第一批数据,然后{active, false}读取任何后续数据块。

您还需要了解指定如何{packet, N}影响事物。请参阅此处:Erlang gen_tcp not receive everything


leg*_*cia 6

这是关于流量控制的:你有一个 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再次呼叫之前接收消息。这可以提供更高的吞吐量,而不必放弃流量控制。