首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python进程池和作用域

Python进程池和作用域
EN

Stack Overflow用户
提问于 2009-09-27 19:55:03
回答 3查看 4K关注 0票数 0

我试图在一个循环中运行自动生成的代码(可能不会终止),用于遗传编程。为此,我尝试使用多处理池,因为我不希望每次创建一个新进程带来很大的性能开销,而且如果池进程运行时间太长,我可以终止它(我不能使用线程)。

基本上,我的程序是

代码语言:javascript
复制
if __name__ == '__main__':    
    pool = Pool(processes=1)            
    while ...:
        source = generate() #autogenerate code
        exec(source)
        print meth() # just a test, prints a result, since meth was defined in source
        result = pool.apply_async(meth)
        try:
            print result.get(timeout=3)  
        except:
           pool.terminate()

这是应该起作用的代码,但不起作用,相反,我得到了

代码语言:javascript
复制
AttributeError: 'module' object has no attribute 'meth'

似乎Pool只看到了冰毒方法,如果它是在最高级定义的。有什么建议可以让它运行动态创建的方法吗?

编辑:问题与进程完全相同,即

代码语言:javascript
复制
source = generated()
exec(source)
if __name__ == '__main__':    
    p = Process(target = meth)
    p.start()

起作用,而

代码语言:javascript
复制
if __name__ == '__main__':    
    source = generated()
    exec(source)
    p = Process(target = meth)
    p.start()

没有,并且在AttributeError中失败了

EN

回答 3

Stack Overflow用户

发布于 2009-09-27 20:33:21

你读过方案编制准则吗?有很多关于全局变量的东西。在Windows下还有更多的限制。您没有说明您在哪个平台上运行,但是如果您在Windows下运行,这可能是问题所在。从上面的链接

全局变量 请记住,如果在子进程中运行的代码试图访问全局变量,那么它看到的值(如果有的话)可能与调用Process.start()时父进程中的值不相同。 但是,仅为模块级常量的全局变量不会引起任何问题。

票数 3
EN

Stack Overflow用户

发布于 2009-09-27 20:39:21

Process (通过池或其他方式)不会有__name__ of '__main__',因此它不会执行任何依赖于该条件的操作--当然包括您所依赖的exec语句,以便找到您的meth

为什么您如此热衷于让这个exec受到这样一个条件的保护,从设计上来说,它在您的子流程中是错误的,但是有一个子进程依赖(自相矛盾!)在执行exec的时候.?!真是让我心烦意乱..。

票数 2
EN

Stack Overflow用户

发布于 2009-09-27 21:51:38

正如我前面评论的那样,您的所有示例都可以在我的Linux盒上正常工作(Debian,Python2.5,processing 0.52,参见下面的测试代码)。

对于您可以从一个进程传输到另一个进程的对象,窗口似乎有许多限制。阅读Nick指出的文档,似乎在窗口os缺少的叉子上,它将运行一个全新的python解释器、导入模块和应该传递的泡菜/解泡菜对象。如果他们不能被腌制的话,我希望你会遇到你遇到的那种问题。

因此,一个完整的(不)工作的例子可能是有用的诊断。答案可能在于你隐藏的不相关的东西。

代码语言:javascript
复制
from processing import Pool
import os

def generated():
    return (
"""
def meth():
    import time
    starttime = time.time()
    pid = os.getpid()
    while 1:
        if time.time() - starttime > 1:
            print "process %s" % pid
            starttime = starttime + 1

""")


if __name__ == '__main__':
    pid = os.getpid()
    print "main pid=%s" % pid
    for n in range(5):
        source = generated() #autogenerate code
        exec(source)
        pool = Pool(processes=1)            
        result = pool.apply_async(meth)
        try:
            print result.get(timeout=3)  
        except:
           pool.terminate()

另一个建议是使用线程。是的,您可以,即使您不知道生成的代码是否停止,或者生成的代码是否有不同的嵌套循环。循环根本不受限制,这正是使用生成器的一点(提取控制流)。我不明白为什么它不能适用于你正在做的事情。同意独立的过程可能是更多的变化,见下面的例子。

代码语言:javascript
复制
import time

class P(object):
    def __init__(self, name):
        self.name = name
        self.starttime = time.time()
        self.lastexecutiontime = self.starttime
        self.gen = self.run()

    def toolong(self):
        if time.time() - self.starttime > 10:
            print "process %s too long" % self.name
            return True
        return False

class P1(P):
    def run(self):
        for x in xrange(1000):
            for y in xrange(1000):
                for z in xrange(1000):
                    if time.time() - self.lastexecutiontime > 1:
                        print "process %s" % self.name
                        self.lastexecutiontime = self.lastexecutiontime + 1
                        yield
        self.result = self.name.uppercase()

class P2(P):
    def run(self):
        for x in range(10000000):
            if time.time() - self.lastexecutiontime > 1:
                print "process %s" % self.name
                self.lastexecutiontime = self.lastexecutiontime + 1
                yield
        self.result = self.name.capitalize()

pool = [P1('one'), P1('two'), P2('three')]
while len(pool) > 0:
    current = pool.pop()
    try:
        current.gen.next()
    except StopIteration:
        print "Thread %s ended. Result '%s'" % (current.name, current.result) 
    else:
        if current.toolong():
            print "Forced end for thread %s" % current.name 
        else:
            pool.insert(0, current)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1484310

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档