我有一些包含两个对象的代码:
class Parent(object):
def __init__():
self.child = None
def stuffParentDoes():
while True:
if self.child is None:
self.child = Child(randint(1,1000))
self.child.start()
else:
print self.child
time.sleep(3)
class Child(Thread):
def __init__(self, name):
super(Child, self).__init__()
self.name = name
def run():
print "%s child doing child stuff" % self.name
time.sleep(3)
parent = Parent()
parent.stuffParentDoes()
我的问题就是这个。如果Child
产生并且正常运行,print Child
会提供类似<Child(Thread-2, started 140038530209536)>
的内容。如果它引发异常,它将打印类似<Child(Thread-2, stopped 140038530209536)>
我的Parent
对象需要知道它已停止,清理它自己的self.child
变量,然后在其位置重新启动另一个Child
。显然这已经过度简化,但希望你明白我的意思。在孩子身上调用join()
也不起作用,因为Parent
还有许多其他事情可做,而join()
阻止导致问题。
修改 最终解决我的问题的是将我的引用移到父对象范围之外的子线程。当引用在全局范围内时,当我需要重新启动子项时,我没有遇到问题。
答案 0 :(得分:1)
以下代码维护了一个&#39;池&#39;线程(又名儿童)。每隔一秒,死线程被移除,并添加新线程以始终保持3个线程。
对于较大的项目,请考虑转到concurrent.futures模块,特别是ThreadPoolExecutor
函数。我还推荐第三方库gevent
(灵活,快速,仅限Python2)和内部模块multiprocessing
(包含池,包含在所有Pythons中)。
import threading, time
from random import random
class Child(threading.Thread):
def run(self):
print "\t%s: child doing child stuff" % self
# sleep 1-3 seconds
time.sleep( 1. + random()*2 )
nchildren = 3
tpool = []
for _ in range(4):
diff = nchildren - len(tpool)
if diff < 1:
print '* okay'
else:
print '* starting {} children'.format(diff)
new_children = [ Child() for _ in xrange(diff) ]
for thread in new_children:
thread.start()
tpool.extend( new_children )
time.sleep(1)
print '* scan...',
tpool = [ thread for thread in tpool
if thread.isAlive()
]
print '{} children'.format(len(tpool))
* starting 3 children
<Child(Thread-1, started 47211446597376)>: child doing child stuff
<Child(Thread-2, started 47211448698624)>: child doing child stuff
<Child(Thread-3, started 47211450799872)>: child doing child stuff
* scan... 3 children
* okay
* scan... 2 children
* starting 1 children
<Child(Thread-4, started 47211448698624)>: child doing child stuff
* scan... 1 children
* starting 2 children
<Child(Thread-5, started 47211450799872)>: child doing child stuff
<Child(Thread-6, started 47211446597376)>: child doing child stuff
* scan... 3 children