上でコメントしたように、すべての例は私の Linux ボックス (Debian Lenny、Python2.5、処理 0.52、以下のテスト コードを参照) で期待どおりに機能しています。
あるプロセスから別のプロセスに転送できるオブジェクトのウィンドウには、多くの制限があるようです。Nick が指摘したドキュメントを読むと、OS の不足しているフォークのウィンドウで、まったく新しい 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)