对于进程之间的通信,一种有趣的起点是帮助页面?socketConnections
和块中标记为“## Not run:”的代码。所以启动一个R进程并运行
con1 <- socketConnection(port = 6011, server=TRUE)
该进程充当服务器,在特定端口上侦听某些信息。现在启动第二个 R 进程并输入
con2 <- socketConnection(Sys.info()["nodename"], port = 6011)
进程 2 中的 con2 与进程 1 上的 con1 建立了套接字连接。回到 con1,写出 R 对象LETTERS
writeLines(LETTERS, con1)
并在 con2 上检索它们。
readLines(con2)
因此,您无需写入磁盘即可在进程之间进行通信。这里也隐含了一些重要的概念,例如,关于阻塞与非阻塞连接。它不限于同一台机器上的通信,只要这些端口可以通过计算机所在的任何网络访问。这是makePSOCKcluster
parallel包中的基础,另外进程1实际上使用system
parallel包中的命令和脚本来启动进程2。返回的对象makePSOCKcluster
是可子设置的,因此您可以将一小部分用于集群以解决特定任务。原则上,您可以安排生成的节点相互通信,而与生成的节点无关。
parallel
一个有趣的练习是使用包中的类似 fork 的命令(在非 Windows 上)来做同样的事情。帮助页面中有一个高级版本?mcparallel
,例如,
p <- mcparallel(1:10)
q <- mcparallel(1:20)
# wait for both jobs to finish and collect all results
res <- mccollect(list(p, q))
但这建立在较低级别sendMaster
和朋友之上(峰值mcparallel
和mccollect
源代码)。
Rmpi 包采用类似于PSOCK
示例的方法,其中管理器使用脚本生成工作人员,并使用 mpi 而不是套接字进行通信。mpi.comm.rank
但是,如果您有一个正常运行的 MPI 实现,那么值得一个周末项目的另一种方法是实现一个脚本,该脚本对不同的数据进行相同的计算,然后使用诸如、mpi.barrier
、mpi.send.Robj
和之类的命令将结果整理到单个节点上mpi.recv.Robj
。
一个有趣的周末项目将使用并行包来实现一个涉及并行计算但不属于 mclapply 种类的工作流程,例如,一个进程从网站收集数据,然后将其传递给另一个绘制漂亮图片的进程。第一个进程的输入很可能是 JSON,但 R 中的通信可能更适合 R 数据对象。