0

我对 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()

当我运行此代码时,我看到打印的消息“深度 X”,其中 X 从 1 到 3,但仅此而已。我还看到在执行结束时(在没有其他事情发生之前)一堆 1 没有对应的 2,这表明对 Pyro 远程对象“self.scheduler.test()”的调用已阻塞。这让我认为这是 Pyro 的问题,而不是进程的问题(例如,如果可能发生这种情况,可用进程用完)。但是,如果我将进程乘法从 10 减少到 2(即,将客户端代码中的“for i in range(10):”替换为“for i in range(2):”),则执行一直到深度5无阻塞...

所以这是我的问题:发生了什么?为什么它会用“for i in range(10):”阻塞?Pyro4远程对象或类似的可能的“客户端”进程是否有限制?是死锁问题吗?

谢谢你。

4

2 回答 2

1

好的。对于任何面临类似问题的人来说,这个问题似乎与可以同时持有远程对象引用的 Pyro 代理数量的限制有关。但是请注意,我只是在推测这一点。这个结论是基于添加

del self.scheduler

就在之前

if self.depth < 5:

在客户端代码中,既限制了活动代理的数量又解决了问题(给它足够的时间,代码使用“for i in range(10):”上升到深度 5)。

编辑:

正如我从这里和一些测试中了解到的那样,THREADPOOL_MINTHREADS 的值与远程对象的最大连接数或代理数相关联。如果我将它设置为 4,当第五个代理尝试访问我的远程对象时,程序会冻结(就像它是死锁一样)。

这里也有一些可能相关的信息。

于 2013-05-31T03:27:23.827 回答
0

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

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

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

这相当于使用,del self.scheduler除非您不必担心放置它的位置 - python 为您完成繁重的工作。

于 2015-02-19T11:22:07.673 回答