简体   繁体   English

在无限循环中使用线程和队列不会关闭线程

[英]Using Threading and Queue in infinite loop does not close threads

I'm struggling to have python periodically run some threaded function and close threads (or reuse the same threads without spawning new ones). 我正在努力让python定期运行一些线程化函数并关闭线程(或重用相同的线程而不会产生新的线程)。 When running the code below it spawns new threads every time the function is ran and eventually the program crashes/stops all together. 当运行下面的代码时,每次运行该函数都会产生新的线程,最终程序一起崩溃/停止。

Is it possible to close threads when the task is done? 完成任务后是否可以关闭线程?

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)

Threads automatically finish when they finish their function. 线程在完成其功能时自动完成。 (You do usually want to keep the thread objects around and join them somewhere, but that's not relevant to your problem here.) (您通常确实希望保留线程对象并将它们join到某个位置,但这与您的问题无关。)

So, if you want them to finish after each task, why did you put a while True: loop inside the function? 因此,如果希望它们在完成每个任务后完成,为什么还要在函数内部放置while True:循环呢? Just that take out and everything will work as you requested. 只需取出即可,一切都会按照您的要求进行。

It can be useful to have threads that run an infinite loop until the queue is done (and then break / return ), but that's a different design. 使线程运行无限循环直到队列完成(然后break / return )可能会很有用,但这是另一种设计。 For that design, you'd just want to start 10 threads at startup, rather than start a new batch of threads for each request. 对于该设计,您只想在启动时启动10个线程,而不是为每个请求启动新一批线程。 (Although in that case, you're just building a bog-standard thread pool, so it may be easier to use the already-existing one in the stdlib—or the slightly higher-level concurrent.futures.ThreadPoolExecutor .) (虽然在这种情况下,你只是建立一个沼泽标准的线程池,所以它可能是更容易使用的STDLIB-或稍高级别的已经存在的一个concurrent.futures.ThreadPoolExecutor 。)

Finally, if what you want is really a new pool of 10 threads for each batch of requests, you can do that. 最后,如果您真正想要的是每批请求一个10个线程的新池,则可以这样做。 It's basically all the complexity of both alternatives, without any advantages over either, but it's doable. 基本上,这是两种选择的全部复杂性,没有任何优势,但这是可行的。 Just as in the persistent thread pool, you'll need to change the thread function to exit when the queue is done. 就像在持久性线程池中一样,您需要将线程功能更改为在队列完成后退出。 And you'll probably need to keep all 10 threads in a list and join them all after joining the queue. 您可能需要将所有10个线程保留在一个列表中,并在加入队列后将它们全部加入。 But that should work. 但这应该可行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM