在无限循环中使用线程和队列不会关闭线程
Using Threading and Queue in infinite loop does not close threads
我正在努力 python 定期 运行 一些线程函数并关闭线程(或重用相同线程而不产生新线程)。当 运行 连接下面的代码时,它会在每次函数 运行 时产生新线程,最终程序 crashes/stops 一起产生。
是否可以在任务完成后关闭线程?
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)
线程在完成其功能时自动结束。 (您通常希望保留线程对象并将它们 join
放在某处,但这与您的问题无关。)
那么,如果您希望他们在每个任务完成后完成,为什么要在函数内放置一个 while True:
循环?只需取出,一切都会按您的要求工作。
让线程 运行 无限循环直到队列完成(然后 break
/return
)可能很有用,但这是不同的设计。对于该设计,您只想在启动时启动 10 个线程,而不是为每个请求启动一批新线程。 (尽管在那种情况下,您只是在构建一个 bog-standard 线程池,因此在 stdlib 中使用 already-existing 线程池可能更容易——或者稍微 higher-level concurrent.futures.ThreadPoolExecutor
.)
最后,如果您真正想要的是为每批请求创建一个包含 10 个线程的新池,您可以这样做。这基本上是两种选择的所有复杂性,没有任何优势,但它是可行的。就像在持久线程池中一样,您需要将线程函数更改为在队列完成时退出。你可能需要将所有 10 个线程都保存在一个列表中,并在加入队列后将它们全部加入。但这应该有效。
我正在努力 python 定期 运行 一些线程函数并关闭线程(或重用相同线程而不产生新线程)。当 运行 连接下面的代码时,它会在每次函数 运行 时产生新线程,最终程序 crashes/stops 一起产生。
是否可以在任务完成后关闭线程?
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)
线程在完成其功能时自动结束。 (您通常希望保留线程对象并将它们 join
放在某处,但这与您的问题无关。)
那么,如果您希望他们在每个任务完成后完成,为什么要在函数内放置一个 while True:
循环?只需取出,一切都会按您的要求工作。
让线程 运行 无限循环直到队列完成(然后 break
/return
)可能很有用,但这是不同的设计。对于该设计,您只想在启动时启动 10 个线程,而不是为每个请求启动一批新线程。 (尽管在那种情况下,您只是在构建一个 bog-standard 线程池,因此在 stdlib 中使用 already-existing 线程池可能更容易——或者稍微 higher-level concurrent.futures.ThreadPoolExecutor
.)
最后,如果您真正想要的是为每批请求创建一个包含 10 个线程的新池,您可以这样做。这基本上是两种选择的所有复杂性,没有任何优势,但它是可行的。就像在持久线程池中一样,您需要将线程函数更改为在队列完成时退出。你可能需要将所有 10 个线程都保存在一个列表中,并在加入队列后将它们全部加入。但这应该有效。