【问题标题】:Comparison of the multiprocessing module and pyro?多处理模块和pyro的比较?
【发布时间】:2010-11-13 09:27:00
【问题描述】:

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

【问题讨论】:

    标签: python rpc multiprocessing pyro


    【解决方案1】:

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

    简答

    多处理:

    • 做面向对象的远程对象感觉很尴尬
    • 轻松轻松的加密(authkey)
    • 通过网络或只是进程间通信
    • 没有像 Pyro 那样的域名服务器额外麻烦(有办法解决这个问题)
    • 编辑:一旦管理器被实例化就不能“注册”对象了!!??
    • 编辑:如果服务器没有启动,客户端会抛出一些“无效参数”异常,而不是仅仅说“连接失败”WTF!?
    • 编辑: BaseManager 文档不正确!没有“启动”方法!?!
    • 编辑:很少有关于如何使用它的例子。

    火焰兵:

    • 简单的远程对象
    • 仅网络通信(仅本地环回)
    • 编辑:这个东西很好用,它喜欢面向对象的对象共享,这让我很喜欢它
    • 编辑: 为什么这不是标准库的一部分,而是试图复制它并惨遭失败的多处理垃圾?

    编辑:我第一次回答这个问题时,我刚刚涉足 2.6 多处理。在我下面显示的代码中,Texture 类已注册并作为代理共享,但是其中的“数据”属性不是。所以猜猜会发生什么,每个进程在纹理代理内部都有一个单独的“数据”属性副本,尽管你可能期望什么。我只是花了无数的时间试图找出在运行时创建共享对象的好模式,我一直在碰壁。这非常令人困惑和沮丧。也许只有我一个人,但环顾四周,人们尝试过的例子很少。

    我不得不做出放弃多处理库并更喜欢 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 遇到过这种尴尬,但可能有一个比上面的例子更干净的解决方案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-04
      • 2017-12-11
      相关资源
      最近更新 更多