版权声明:本文为博主原创文章,未经博主允许请尽情转载。 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的自动垃圾回收机制,如果一个对象不存在对它的引用,那么它将被回收掉。所以上面的方法是可以解决的。