Erlang 最开始吸引我的地方之一是 Actor 模型。不同进程同时运行并通过异步消息传递进行交互的想法。
我刚刚开始深入了解 OTP,尤其是查看 gen_server。我见过的所有示例 - 并且授予它们是教程类型的示例 - 使用 handle_call()
而不是 handle_cast()
实现模块行为。
我觉得这有点令人困惑。据我所知,handle_call
是一个同步操作:调用者被阻塞直到被调用者完成并返回。这似乎与异步消息传递理念背道而驰。
我即将启动一个新的 OTP 应用程序。这似乎是一个基本的架构决策,所以我想在开始之前确保我理解。
我的问题是:
handle_call
而不是 handle_cast
? 最佳答案
如果你想得到结果,
handle_call
真的很常见。如果您对通话结果不感兴趣,请使用 handle_cast
.当handle_call
被使用,调用者会阻塞,是的。这大部分时间都可以。让我们看一个例子。如果您有一个将文件内容返回给客户端的 Web 服务器,那么您将能够处理多个客户端。每个客户端都必须等待文件内容被读取,所以使用
handle_call
在这种情况下会很好(除了愚蠢的例子)。当您确实需要发送请求、进行一些其他处理然后稍后获得回复的行为时,通常会使用两次调用(例如,一次强制转换和一次调用以获取结果)或正常的消息传递。但这是一个相当罕见的情况。
handle_call
将在通话期间阻止该过程。这将导致客户排队等待回复,因此整个事情将按顺序运行。如果你想要并行代码,你必须编写并行代码。唯一的方法是运行多个进程。
所以,总结一下:
handle_call
将阻塞调用者并在调用期间占用调用的进程。 关于Erlang/OTP : Synchronous vs. 异步消息传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6031910/