Python Pyro4远程对象块(如死锁)

Python Pyro4远程对象块(如死锁),python,multiprocessing,deadlock,pyro,Python,Multiprocessing,Deadlock,Pyro,我对Python Pyro4远程对象有一个问题,它们的行为就像死锁一样。下面是如何重现问题(在Windows中)。启动名称服务器: set PYRO_HMAC_KEY=some_key python -m Pyro4.naming 然后运行远程对象服务器: import Pyro4 import sys class Scheduler: def test(self): pass if __name__ == '__main__': sys.except

我对Python Pyro4远程对象有一个问题,它们的行为就像死锁一样。下面是如何重现问题(在Windows中)。启动名称服务器:

set PYRO_HMAC_KEY=some_key
python -m Pyro4.naming
然后运行远程对象服务器:

import Pyro4
import sys


class Scheduler:
    def test(self):
        pass

if __name__ == '__main__': 

    sys.excepthook = Pyro4.util.excepthook

    scheduler = Scheduler()

    Pyro4.config.HMAC_KEY='some_key'  

    deamon = Pyro4.Daemon()
    ns = Pyro4.locateNS()
    ns.register("scheduler", deamon.register(scheduler))

    deamon.requestLoop()
然后运行客户端:

import sys
from multiprocessing import Process
import Pyro4

class BWModule(Process):

    def __init__(self):
        Process.__init__(self)
        self.depth = 1


    def run(self): 

        Pyro4.config.HMAC_KEY='some_key'       
        self.scheduler = Pyro4.Proxy("PYRONAME:scheduler")                

        print "1"
        sys.stdout.flush()         
        self.scheduler.test()
        print "2"
        sys.stdout.flush()         

        print "depth", self.depth
        sys.stdout.flush() 

        if self.depth < 5:
            for i in range(10):
                newblock = self.duplicate()
                newblock.depth = self.depth + 1
                newblock.start()


    def duplicate(self):
        dup = type(self)()
        return dup



if __name__ == '__main__': 

    sys.excepthook = Pyro4.util.excepthook

    No1 = BWModule()    
    No1.start()
导入系统 从多处理导入进程 进口烟火4 类别模块(流程): 定义初始化(自): 进程。初始化(自) self.depth=1 def运行(自): Pyro4.config.HMAC_KEY='some_KEY' self.scheduler=Pyro4.Proxy(“PYRONAME:scheduler”) 打印“1” sys.stdout.flush() self.scheduler.test() 打印“2” sys.stdout.flush() 打印“深度”,self.depth sys.stdout.flush() 如果自深度小于5: 对于范围(10)内的i: newblock=self.duplicate() newblock.depth=self.depth+1 newblock.start() def副本(自身): dup=类型(自身)() 返回dup 如果uuuu name uuuuuu='\uuuuuuu main\uuuuuuu': sys.excepthook=Pyro4.util.excepthook No1=BWModule() 开始 当我运行这段代码时,我看到打印的消息“depth X”,X从1到3,但没有更多。我还看到在执行结束时(在没有其他事情发生之前),一堆1没有相应的2,这表明Pyro远程对象“self.scheduler.test()”的调用已被阻止。这使我认为这是Pyro的问题,而不是进程的问题(例如,如果可能的话,可用进程将耗尽)。但是,如果我将进程乘法从10减少到2(即,在客户端代码中将“范围内的I(10):”替换为“范围内的I(2):”),那么执行将一直执行到深度5,而不会阻塞

我的问题是:发生了什么?为什么它会用“范围(10)内的i:”来阻止?Pyro4远程对象或类似对象是否有可能的“客户端”进程限制?这是一个死锁问题吗


谢谢。好的。对于任何面临类似问题的人来说,这个问题似乎与能够同时在远程对象上保存引用的Pyro代理数量的限制有关。然而,请注意,我只是在猜测这一点。这一结论基于以下事实:

del self.scheduler
就在之前

if self.depth < 5:
如果self.depth<5:
在客户机代码中,既限制了活动代理的数量,又修复了问题(给它足够的时间,代码使用“for i in range(10):”)上升到深度5)

编辑:

据我从一些测试中了解,THREADPOOL_MINTHREADS的值与远程对象的最大连接数或代理数相关联。如果我将其设置为4,当第五个代理尝试访问我的远程对象时,程序将冻结(很像死锁)


还有一些可能的相关信息

刚刚面临一个类似的问题,一个更简洁的方法可能是改变

 self.scheduler = Pyro4.Proxy("PYRONAME:scheduler") 

这相当于使用
del self.scheduler
,只是您不必担心将其放置在何处—python为您完成繁重的工作

 with Pyro4.Proxy("PYRONAME:scheduler") as self.scheduler:
    # Rest of code using self.scheduler
 #Rest of code not using self.scheduler