python "threads can only be started once"解决方法

版权声明:本文为博主原创文章,未经博主允许请尽情转载。 https://blog.csdn.net/yanghuan313/article/details/52985393

我最近根据要求又在修改爬虫,想让它一直爬取,不想在linux写定时脚本,不方便也太麻烦,干脆直接加一个守护线程,让它去管理这些子线程的工作,如果哪个线程死掉了,再开一次就好了。

import threading
import time

class Thread(threading.Thread):
    def __init__(self, i):
        threading.Thread.__init__(self)
        self.name = 'crawlers - ' + str(i+1)

    def run(self):
        print 'test --- ' + self.name
        # do something


class Controller(threading.Thread):
    def __init__(self, threads):
        threading.Thread.__init__(self)
        self.daemon = True
        self.threadList = threads

    def run(self):
        for each in self.threadList:
            each.start()
        while True:
            for a in xrange(5):
                if not self.threadList[a].isAlive():
                    self.threadList[a].start()
                sleep(3600) # 每个小时判断一下

if __name__ == '__main__':
    threads = []
    for i in xrange(5):
        t = Thread(i)
        threads.append(t)
    c = Controller(threads)
    c.start()
    c.join()

所以我就写了如上的代码,结果,报错了:

RuntimeError: threads can only be started once

what???仔细检查代码没有问题,应该是线程结束了以后才重新 start 的,难道要手动结束线程?尝试了一下,好像不对劲,并没有这个概念。

查找python API,结果才发现了问题:

这里写图片描述

原来是自己没弄清楚,所以解决办法也就很清晰了,重新创建一个对象:

def run(self):
        for each in self.threadList:
            each.start()
        while True:
            for a in xrange(5):
                if not self.threadList[a].isAlive():
                    self.threadList[a] = Thread(a)
                    self.threadList[a].start()
                sleep(3600) # 每个小时判断一下

那会不会出现这样一个问题,过去的对象不断占用内存?
答案是不会的,因为python的自动垃圾回收机制,如果一个对象不存在对它的引用,那么它将被回收掉。所以上面的方法是可以解决的。

猜你喜欢

转载自blog.csdn.net/yanghuan313/article/details/52985393