我很难让python定期运行一些线程函数并关闭线程(或重用相同的线程而不产生新的线程)。运行下面的代码时,每次运行该函数时都会产生新的线程,最终程序崩溃/停止。
完成任务后是否可以关闭线程?
import threading
from Queue import Queue
import time
import socket
number_of_threads = 10
def check_server(address):
s = socket.socket()
s.settimeout(1)
try:
s.connect((address, 443))
return True
except:
return False
def get_online_servers(subnet):
def threader():
while True:
global online_servers
ip = q.get()
a = check_server(ip)
if a:
online_servers.append(ip)
q.task_done()
q = Queue()
for x in range(number_of_threads):
t = threading.Thread(target=threader)
t.daemon = False
t.start()
for i in range(1, 20):
ip = "{}.{}".format(subnet, i)
q.put(ip)
q.join()
return online_servers
if __name__ == '__main__':
while True:
online_servers = []
result = get_online_servers("10.0.0")
print result
time.sleep(5)
答案 0 :(得分:2)
线程在完成其功能后自动完成。 (你通常希望保留线程对象并将它们join
放在某处,但这与你的问题无关。)
那么,如果你希望它们在每个任务之后完成,你为什么要在函数内放一个while True:
循环?只需要拿出来,一切都会按照您的要求运作。
让线程运行无限循环直到队列完成(然后break
/ return
)会很有用,但这是一个不同的设计。对于该设计,您只想在启动时启动10个线程,而不是为每个请求启动新的线程批处理。 (虽然在这种情况下,你只是构建一个标准的标准线程池,所以在stdlib中使用已经存在的线程池可能更容易 - 或者稍微更高级别的concurrent.futures.ThreadPoolExecutor
。)
最后,如果您想要的是每批请求的10个线程的新池,您可以这样做。它基本上都是两种选择的复杂性,没有任何优势,但它是可行的。就像在持久性线程池中一样,您需要更改线程函数以在队列完成时退出。并且您可能需要将所有10个线程保留在列表中并在加入队列后将它们全部连接起来。但这应该有用。