多处理模块和pyro的比较?

时间:2009-07-23 13:34:08

标签: python rpc multiprocessing pyro

我使用pyro对计算群集上的并行作业进行基本管理。我刚搬到了一个集群,我将负责使用每个计算节点上的所有核心。 (在以前的集群中,每个核心都是一个单独的节点。)python multiprocessing模块似乎非常适合这种情况。我注意到它也可以用于remote-process communication。如果有人使用这两个框架进行远程进程通信,我将不胜感激他们如何相互叠加。多处理模块的明显优势在于它内置于2.6。除此之外,我很难说哪个更好。

1 个答案:

答案 0 :(得分:15)

编辑:我正在改变我的答案,以免你痛苦。多处理是不成熟的,BaseManager上的文档是 INCORRECT ,如果你是一个想要在运行时动态创建共享对象的面向对象的思想家,使用PYRO或你将会严重注册它!如果您只是使用共享队列进行函数式编程,那么您可以预先注册,就像所有愚蠢的例子一样适合您。

简答

多处理:

  • 做面向对象的远程对象感觉很尴尬
  • Easy breezy crypto(authkey)
  • 通过网络或仅进行进程间通信
  • 没有名字服务员在Pyro中有额外的麻烦(有办法解决这个问题)
  • 编辑:管理员实例化后无法“注册”对象!! ??
  • 编辑:如果服务器未启动,客户端会抛出一些“无效参数”异常,而不是仅仅说“无法连接”WTF!?
  • 编辑:BaseManager文档不正确!没有“开始”的方法!?!
  • 编辑:关于如何使用它的示例很少。

的Pyro:

  • 简单的远程对象
  • 仅限网络通信(仅限本地环回)
  • 编辑:这件事只是工作,它喜欢面向对象的对象共享,这让我喜欢它
  • 编辑:为什么这不是标准库的一部分而不是试图复制它并且失败的多处理废话?

编辑:我第一次回答这个问题时,我刚刚进入2.6多处理阶段。在下面显示的代码中,Texture类被注册并作为代理共享,但其中的“data”属性不是。因此,猜测会发生什么,每个进程都有一个单独的纹理代理内部“数据”属性的副本,尽管你可能会期望。我只花了不少时间试图找出在运行时如何创建共享对象的好模式,并且我一直跑到砖墙里。这令人非常困惑和令人沮丧。也许这只是我,但环顾一下人们尝试过的例子并不像它。

我不得不做出一个痛苦的决定,即删除多处理库并优先考虑Pyro直到多处理更成熟。虽然最初我很高兴能够学习内置到python中的多处理,但我现在对它非常厌恶,并且宁愿安装Pyro软件包很多次,高兴的是这样一个漂亮的库存在于python中。

长答案

我在过去的项目中使用了Pyro并且对它非常满意。我也开始使用2.6中的多处理新功能。

通过多处理,我发现允许根据需要创建共享对象有点尴尬。看起来,在年轻时,多处理模块更适合于功能编程,而不是面向对象。然而,这并不完全正确,因为它可以做到,我只是受到“注册”电话的限制。

例如:

manager.py:

from multiprocessing import Process
from multiprocessing.managers import BaseManager

class Texture(object):
   def __init__(self, data):
        self.data = data

   def setData(self, data):
      print "Calling set data %s" % (data)
      self.data = data

   def getData(self):
      return self.data

class TextureManager(BaseManager):
   def __init__(self, address=None, authkey=''):
      BaseManager.__init__(self, address, authkey)
      self.textures = {}

   def addTexture(self, name, texture):
      self.textures[name] = texture

   def hasTexture(self, name):
      return name in self.textures

server.py:

from multiprocessing import Process
from multiprocessing.managers import BaseManager
from manager import Texture, TextureManager

manager = TextureManager(address=('', 50000), authkey='hello')

def getTexture(name):
   if manager.hasTexture(name):
      return manager.textures[name]
   else:
      texture = Texture([0]*100)
      manager.addTexture(name, texture)
      manager.register(name, lambda: texture)

TextureManager.register("getTexture", getTexture)


if __name__ == "__main__":
   server = manager.get_server()
   server.serve_forever()

client.py:

from multiprocessing import Process
from multiprocessing.managers import BaseManager
from manager import Texture, TextureManager

if __name__ == "__main__":
   manager = TextureManager(address=('127.0.0.1', 50000), authkey='hello')
   manager.connect()
   TextureManager.register("getTexture")
   texture = manager.getTexture("texture2")
   data = [2] * 100
   texture.setData(data)
   print "data = %s" % (texture.getData())

我所描述的尴尬来自server.py,我在其中注册一个getTexture函数,从TextureManager中检索某个名称的函数。正如我正在讨论的那样,如果我使TextureManager成为一个可共享的对象来创建/检索可共享的纹理,那么可能会删除尴尬。嗯,我还在玩,但你明白了。我不记得使用pyro遇到这种尴尬,但可能有一个比上面的例子更清晰的解决方案。