父进程清理引发异常的线程

时间:2014-06-06 17:12:14

标签: python multithreading concurrency python-multithreading

我有一些包含两个对象的代码:

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()阻止导致问题。

修改 最终解决我的问题的是将我的引用移到父对象范围之外的子线程。当引用在全局范围内时,当我需要重新启动子项时,我没有遇到问题。

1 个答案:

答案 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