我使用 pyro用于计算集群上并行作业的基本管理。我刚搬到一个集群,在那里我将负责使用每个计算节点上的所有内核。 (在以前的集群中,每个核心都是一个单独的节点。)python multiprocessing模块似乎很适合这个。我注意到它也可以用于 remote-process communication .如果有人使用这两种框架进行远程进程通信,我将很高兴听到它们如何相互比较。 multiprocessing 模块的明显好处是它是从 2.6 开始内置的。除此之外,我很难说哪个更好。
最佳答案
编辑:我正在改变我的答案,这样你就可以避免痛苦。 multiprocessing 不成熟,BaseManager 上的文档不正确,如果你是一个面向对象的思想家,想在运行时即时创建共享对象,使用 PYRO 否则你会严重遗憾!如果您只是使用共享队列进行函数式编程,您可以像所有愚蠢的示例一样预先注册,这对您来说非常好。
多处理:
火焰兵:
编辑: 第一次回答这个问题时,我刚刚深入研究了 2.6 多处理。在我下面显示的代码中,Texture 类作为代理注册和共享,但其中的“数据”属性不是。所以猜猜会发生什么,每个进程在纹理代理内部都有一个单独的“数据”属性副本,尽管您可能会这样。我只是花了数不清的时间试图找出在运行时创建共享对象的良好模式,我一直在碰砖墙。这一直很令人困惑和沮丧。也许只有我一个人是这样认为的,但环顾四周人们尝试过的为数不多的例子,它看起来并不像。
在多处理更加成熟之前,我不得不做出放弃多处理库并更喜欢 Pyro 的痛苦决定。虽然最初我很高兴学习 python 中内置的多处理,但现在我对它感到非常厌恶,宁愿多次安装 Pyro 包,并为 python 存在如此漂亮的库感到高兴。
我在过去的项目中使用过 Pyro,并且对它非常满意。我也开始使用 2.6 中的新多处理。
对于多处理,我发现允许根据需要创建共享对象有点尴尬。看起来,在它年轻的时候,多处理模块更适合函数式编程而不是面向对象。然而,这并不完全正确,因为这是可能的,我只是觉得受到“注册”电话的限制。
例如:
管理器.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
服务器.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()
客户端.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 时遇到过这种尴尬,但可能有一个比上面的例子更简洁的解决方案。
关于python - 多处理模块和pyro的比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1171767/
假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack
我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah
我有一个围绕一些对象的包装类,我想将这些对象用作散列中的键。包装对象和解包装对象应映射到相同的键。一个简单的例子是这样的:classAattr_reader:xdefinitialize(inner)@inner=innerenddefx;@inner.x;enddef==(other)@inner.x==other.xendenda=A.new(o)#oisjustanyobjectthatallowso.xb=A.new(o)h={a=>5}ph[a]#5ph[b]#nil,shouldbe5ph[o]#nil,shouldbe5我试过==、===、eq?并散列所有无济于事。
我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or
我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co