正如我在上面评论的那样,您的所有示例都在我的 Linux 机器上按预期工作(Debian Lenny,Python2.5,处理 0.52,请参见下面的测试代码)。
您可以从一个进程传输到另一个进程的对象的窗口似乎有很多限制。阅读 Nick 指出的文档,似乎在窗口中缺少 fork 的操作系统将运行一个全新的 python 解释器导入模块和应该传递的 pickle/unpickle 对象。如果不能腌制它们,我希望您会遇到遇到的那种问题。
因此,一个完整的(非)工作示例可能对诊断有用。答案可能在你隐藏的无关紧要的事情中。
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)