gpt4 book ai didi

python - 如何在 Python 中关闭线程?

转载 作者:太空宇宙 更新时间:2023-11-03 12:33:54 25 4
gpt4 key购买 nike

我有太多线程未完成的问题。我认为队列命令 .join() 只是关闭队列而不是使用它的线程。

在我的脚本中,我需要检查 280k 域,并为每个域获取他的 MX 记录列表,并获取服务器的 IPv6 地址(如果有)。

我使用了线程,感谢它们让脚本快了好几倍。但是有一个问题,尽管队列有 join(),但事件线程的数量不断增加,直到出现错误,提示无法创建任何新线程(操作系统的限制?)。

当我从数据库中检索新域时,如何在每个 For 循环后终止/关闭/停止/重置线程?

线程类定义...

class MX_getAAAA_thread(threading.Thread):
def __init__(self,queue,id_domain):
threading.Thread.__init__(self)
self.queue = queue
self.id_domain = id_domain


def run(self):
while True:
self.mx = self.queue.get()

res = dns.resolver.Resolver()
res.lifetime = 1.5
res.timeout = 0.5

try:
answers = res.query(self.mx,'AAAA')
ip_mx = str(answers[0])
except:
ip_mx = "N/A"

lock.acquire()

sql = "INSERT INTO mx (id_domain,mx,ip_mx) VALUES (" + str(id_domain) + ",'" + str(self.mx) + "','" + str(ip_mx) + "')"
try:
cursor.execute(sql)
db.commit()
except:
db.rollback()

print "MX" , '>>' , ip_mx, ' :: ', str(self.mx)

lock.release()
self.queue.task_done()

正在使用线程类...(主要的For-loop不在这里,这只是他 body 的一部分)

try:
answers = resolver.query(domain, 'MX')

qMX = Queue.Queue()
for i in range(len(answers)):
t = MX_getAAAA_thread(qMX,id_domain)
t.setDaemon(True)
threads.append(t)
t.start()

for mx in answers:
qMX.put(mx.exchange)

qMX.join()

except NoAnswer as e:
print "MX - Error: No Answer"
except Timeout as etime:
print "MX - Error: dns.exception.Timeout"

print "end of script"

我尝试过:

for thread in threads:
thread.join()

队列完成后,但 thread.join() 永远不会停止等待,尽管事实上不需要等待,因为当 queue.join() 执行时,线程无事可做。

最佳答案

当我的线程涉及像这样的无限循环时,我经常做的是将条件更改为我可以从外部控制的东西。例如像这样:

def run(self):
self.keepRunning = True
while self.keepRunning:
# do stuff

这样,我可以从外部更改 keepRunning 属性并将其设置为 false,以便在下次检查循环条件时优雅地终止线程。

顺便说一句。因为您似乎为放入队列的每个项目都生成了一个线程,所以您甚至根本不需要线程循环,尽管我认为您应该始终强制执行可以创建的线程的最大限制这样(即 for i in range(min(len(answers), MAX_THREAD_COUNT)):)

备选

在您的情况下,您可以重用线程,而不是在每次 for 循环迭代中终止线程。根据我从您的线程源中收集到的信息,使线程对于迭代唯一的是您在创建线程时设置的 id_domain 属性。但是,您也可以只在队列中提供它,这样线程就完全独立了,您可以重用它们。

这可能是这样的:

qMX = Queue.Queue()
threads = []
for i in range(MAX_THREAD_COUNT):
t = MX_getAAAA_thread(qMX)
t.daemon = True
threads.append(t)
t.start()

for id_domain in enumerateIdDomains():
answers = resolver.query(id_domain, 'MX')
for mx in answers:
qMX.put((id_domain, mx.exchange)) # insert a tuple

qMX.join()

for thread in threads:
thread.keepRunning = False

当然,您需要稍微更改一下线程:

class MX_getAAAA_thread(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue

def run(self):
self.keepRunning = True
while self.keepRunning:
id_domain, mx = self.queue.get()
# do stuff

关于python - 如何在 Python 中关闭线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14548111/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com