首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Erlang的rpc:multicall/4与rpc:pmap/3的区别

Erlang的rpc:multicall/4与rpc:pmap/3的区别
EN

Stack Overflow用户
提问于 2017-03-12 23:15:25
回答 2查看 630关注 0票数 2

我目前正在尝试在多个节点上运行一些Elixir代码,我已经使用了两种方法: 1) :rpc.multicall/4 & 2) :rpc.pmap/3

我可以看到两者都在多个节点上运行代码,并且我知道这些调用的结果是不同的(tuple vs list)。

这两个函数之间是否还有其他重要的区别,或者这两个函数是否等价,唯一的区别在于它们的调用方式和返回值?

提前感谢!

EN

回答 2

Stack Overflow用户

发布于 2017-03-13 05:08:27

它们真的彼此不同,

pmap将执行类似于:list.map (这里更多是http://erlang.org/doc/man/lists.html)的映射,但其优点是,只要节点可用、已连接并且列表中有值可供执行映射,此调用就会在节点之间发生。

其他方式的multicall将始终执行相同的调用,在多个节点中使用相同的参数。multicall/4在所有连接的节点中执行相同的函数调用。rpc在开头有一个额外的参数,即将执行multicall/5的节点的列表。

当我们有一个由3个shell组成的集群时,更好地举例说明

  • iex --sname node1
  • iex --sname node2
  • iex --sname node3

然后我们在node1执行时相互连接

代码语言:javascript
复制
Node.connect :"node2@mymachine"
# => false
Node.connect :"node3@mymachine"
# => false

我们可以定义一个函数,它将2个值相加,并返回执行此操作的节点的值,如下所示:

代码语言:javascript
复制
iex(node1@mymachine)> defmodule Operation do
...(node1@mymachine)>   def sum(a, b), do: {Node.self(), a + b}
...(node1@mymachine)> end

有必要在每个shell中定义这个函数。因此,现在可以只用多个值调用我们的pmap,看看会发生什么。在我的电脑里,从node1调用时发生了这样的事情。

代码语言:javascript
复制
iex(node1@mymachine)> :rpc.pmap {Operation, :sum}, [1], [1,2,3]
[node3@mymachine: 2, node2@mymachine: 3, node1@mymachine: 4]

对于每个节点,在最后一个位置使用不同的参数调用sum/2函数,从而导致不同的输出。如果我的:rpc.map/3的最后一个参数是一个元素少于可用节点的列表,那么就没有必要调用所有节点。但这些都是完成操作所必需的。如果我传递了很多参数,它会以一种更平衡的方式返回调用。您可以尝试在每个节点上执行:rpc.pmap {Operation, :sum}, [1], Enum.to_list 1..20,然后自己查看结果。

另一方面,当我们使用:rpc.multicall/5时,您传递的不是要并行执行的参数列表,而是要在多个节点中同时执行的相同参数。例如

代码语言:javascript
复制
iex(node1@mymachine)> :rpc.multicall(Operation, :sum, [2, 2], :infinity)
# => {[node1@mymachine: 4, node2@mymachine: 4, node3@mymachine: 4], []}

最后一个参数是在每个节点中执行的超时时间,如果满足这个超时时间,这个节点的结果将不会显示在元组的第一个列表中。

使用:rpc.multicall/5,可以将此调用将被执行的节点列表作为第一个参数进行传递。例如,如果我只想在任何节点内的node2和node3中执行,那么我只需要执行

代码语言:javascript
复制
iex(node1@mymachine)> :rpc.multicall([:"node2@mymachine", :"node3@mymachine"] Operation, :sum, [2, 2], :infinity)
# => {[node2@mymachine: 4, node3@mymachine: 4], []}

需要注意的一件事是,:rpc.multicall/4:rpc.pmap/3都是在没有Node的情况下工作的,这是因为对于erlangvm,每当您启动iexerl时,您就已经在一个节点集群上了。

票数 3
EN

Stack Overflow用户

发布于 2017-03-13 01:21:40

从文档中找到。

:rpc.multicall/5

多路呼叫是从一个客户端并发发送到多个服务器的远程过程调用。这对于从一组节点收集信息,或者调用一组节点上的函数以实现一些副作用非常有用。

:rpc.pmap/3

并行地为List1中的每个元素Elem计算apply(Module,Function,Elem|ExtraArgs)。按与List1相同的顺序返回返回值列表。

因此,multicall/5将在给定的一组节点上调用单个函数。它将返回一个元组,其中第一个元素是结果列表,第二个元素是由于某种原因没有完成函数的节点列表。

pmap/3类似于调用map,不同之处在于工作可能在不同的节点上完成,也可能不在不同的节点上完成。重要的是要知道,结果列表仍将具有与起始列表相同的顺序。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42749089

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档