我试图在一个循环中运行自动生成的代码(可能不会终止),用于遗传编程。为此,我尝试使用多处理池,因为我不希望每次创建一个新进程带来很大的性能开销,而且如果池进程运行时间太长,我可以终止它(我不能使用线程)。
基本上,我的程序是
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()这是应该起作用的代码,但不起作用,相反,我得到了
AttributeError: 'module' object has no attribute 'meth'似乎Pool只看到了冰毒方法,如果它是在最高级定义的。有什么建议可以让它运行动态创建的方法吗?
编辑:问题与进程完全相同,即
source = generated()
exec(source)
if __name__ == '__main__':
p = Process(target = meth)
p.start()起作用,而
if __name__ == '__main__':
source = generated()
exec(source)
p = Process(target = meth)
p.start()没有,并且在AttributeError中失败了
发布于 2009-09-27 20:33:21
你读过方案编制准则吗?有很多关于全局变量的东西。在Windows下还有更多的限制。您没有说明您在哪个平台上运行,但是如果您在Windows下运行,这可能是问题所在。从上面的链接
全局变量 请记住,如果在子进程中运行的代码试图访问全局变量,那么它看到的值(如果有的话)可能与调用Process.start()时父进程中的值不相同。 但是,仅为模块级常量的全局变量不会引起任何问题。
发布于 2009-09-27 20:39:21
Process (通过池或其他方式)不会有__name__ of '__main__',因此它不会执行任何依赖于该条件的操作--当然包括您所依赖的exec语句,以便找到您的meth。
为什么您如此热衷于让这个exec受到这样一个条件的保护,从设计上来说,它在您的子流程中是错误的,但是有一个子进程依赖(自相矛盾!)在执行exec的时候.?!真是让我心烦意乱..。
发布于 2009-09-27 21:51:38
正如我前面评论的那样,您的所有示例都可以在我的Linux盒上正常工作(Debian,Python2.5,processing 0.52,参见下面的测试代码)。
对于您可以从一个进程传输到另一个进程的对象,窗口似乎有许多限制。阅读Nick指出的文档,似乎在窗口os缺少的叉子上,它将运行一个全新的python解释器、导入模块和应该传递的泡菜/解泡菜对象。如果他们不能被腌制的话,我希望你会遇到你遇到的那种问题。
因此,一个完整的(不)工作的例子可能是有用的诊断。答案可能在于你隐藏的不相关的东西。
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()另一个建议是使用线程。是的,您可以,即使您不知道生成的代码是否停止,或者生成的代码是否有不同的嵌套循环。循环根本不受限制,这正是使用生成器的一点(提取控制流)。我不明白为什么它不能适用于你正在做的事情。同意独立的过程可能是更多的变化,见下面的例子。
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)https://stackoverflow.com/questions/1484310
复制相似问题