在哪种情况下我们应该在 Erlang 中使用 The Hybrid Approach Socket?

Posted

技术标签:

【中文标题】在哪种情况下我们应该在 Erlang 中使用 The Hybrid Approach Socket?【英文标题】:which case we should use The Hybrid Approach Socket in Erlang? 【发布时间】:2015-11-10 00:45:22 【问题描述】:

Programing Erlang 在第 17.2 章中说

Erlang 套接字可以以三种模式之一打开:主动、一次主动或被动

...

您可能认为对所有服务器使用被动模式是正确的方法。不幸的是,当我们处于被动模式时,我们只能等待来自一个套接字的数据。这对于编写必须等待来自多个套接字的数据的服务器是没有用的。

我只是看不懂这句话这对于编写必须等待来自多个套接字的数据的服务器来说是无用的

在我看来,如果我不能说服客户,我不应该使用主动模式。

但是我可以为每个客户端创建一个具有被动模式的并行服务器(一个客户端一个 Erlng 进程)。

也许它说一个用于多个套接字的 Erlang 进程。但是我无法想象这个案例的例子。

你能告诉我更多关于它的信息吗?

谢谢!

【问题讨论】:

另外请注意,这本书已经过时了,因为有四种模式:主动、主动 N、主动一次和被动。 【参考方案1】:

不幸的是,当我们处于被动模式时,我们只能等待来自一个套接字的数据。这对于编写必须等待来自多个套接字的数据的服务器来说是无用的。

我会说这不是一个非常有说服力的反对被动套接字的论据。几乎在所有情况下,每个套接字都有一个 Erlang 进程,不会出现这个问题。

反对被动套接字的一个更好的论点是,在等待数据时(使用gen_tcp:recv),进程无法接收来自其他 Erlang 进程的消息。这些消息可能是计算、关闭请求等的结果。

也就是说,当使用 active 或 active-once 模式时,您的 receive 看起来像这样:

receive
    tcp, Socket, Data ->
        %% do something with Data
        %% then reactivate the socket
        ok = inet:setopts(Socket, [active,once]),
        loop(Socket);
    result, Result ->
        %% send Result back to socket
        ok = gen_tcp:send(Socket, Result),
        loop(Socket);
    stop ->
        %% stop this process
        exit(normal)
end

使用此代码,无论是套接字上的传入数据还是来自另一个 Erlang 进程的消息,都会先处理先到达的事件。

另一方面,如果您使用 gen_tcp:recv 接收数据,您将阻止该呼叫,无法及时响应 result, Resultstop

【讨论】:

以上是关于在哪种情况下我们应该在 Erlang 中使用 The Hybrid Approach Socket?的主要内容,如果未能解决你的问题,请参考以下文章

在这种情况下我应该使用哪种 Erlang 行为,即 gen_server 或 gen_fsm

CachedNetworkImage 和 CachedNetworkImageProvider 有啥区别?应该分别用在哪种情况下?

在哪种情况下使用 JPA @JoinTable 注释?

我们什么时候应该使用Spark-sql,什么时候应该使用Spark RDD

递归与手动堆栈 - 在哪种情况下哪个是首选?

递归与手动堆栈 - 在哪种情况下首选哪个?