python-3.x 如何限制Tkinter按钮点击创建的线程数量?

sqyvllje  于 2023-05-30  发布在  Python
关注(0)|答案(2)|浏览(231)

我正在学习线程和GUI与tkinter,我有一个问题要问你:
首先是我的代码:

import tkinter as tk
from queue import Queue
import threading

num_threads = 8
enclosure_queue = Queue()

def deviceconnector(i, q):
    ip = q.get()
    print("Do something")

def main():
    for i in range(num_threads):

        thread = threading.Thread(target=deviceconnector, args=(i, enclosure_queue,), daemon=True)

        thread.start()
    print(threading.active_count())

root = tk.Tk()
button_frame = tk.Frame(root)
button_frame.pack(side="right")
run_button = tk.Button(button_frame, text="Run HC", command=main)
run_button.grid(padx=10, pady=10)

if __name__ == '__main__':
    root.mainloop()

结果只是一个带有按钮的窗口,该按钮将执行触发线程到deviceconnector的主函数,我将使用该函数连接到使用netmiko的设备,在调用该函数后,一切都正常工作,我打印thread.active_count(),我可以看到每次单击按钮时计数都在增加,在我的监视器上,我也可以看到越来越多的ram被消耗。
那么,有没有一种方法可以清理这些线程,并保持最初的8?
Here is a pic
我所期望的是保持最初的8个线程后,按钮被点击,如果这是可能的

ia2d9nvy

ia2d9nvy1#

使用threading模块和tkinter库创建简单GUI应用程序的示例。应用程序使用多个线程执行设备连接。

import threading
import datetime
import time
import tkinter as tk
from queue import Queue

num_devices = 10
num_threads = 3

def deviceconnector(ip):
    # Simulate device connection by sleeping for 2 seconds
    time.sleep(2)
    print(f"done {ip} at {datetime.datetime.now()}\n")

def _queued_methods(queue: Queue) -> None:
    """Do queued tasks"""
    while not queue.empty():
        method, params = queue.get()
        # Execute the method "deviceconnector" with the provided parameters "ip=10.0.0.1"
        method(**params)
        queue.task_done()

def main() -> None:
    # Create a queue to store tasks
    queue: Queue = Queue()
    for i in range(num_devices):
        # Add device connection tasks to the queue
        queue.put((deviceconnector, {"ip": f"10.0.0.{i}"}))

    for idx in range(num_threads):
        # Create threads that execute queued tasks
        thread = threading.Thread(target=_queued_methods, args=(queue,))
        # Start the thread
        thread.start()
    # Wait for all tasks in the queue to be completed
    queue.join()

if __name__ == '__main__':
    root = tk.Tk()
    button_frame = tk.Frame(root)
    button_frame.pack(side="right")
    run_button = tk.Button(button_frame, text="Run HC", command=main)
    run_button.grid(padx=10, pady=10)
    root.mainloop()

输出

done 10.0.0.2 at 2023-05-28 08:39:12.786582
done 10.0.0.0 at 2023-05-28 08:39:12.786582
done 10.0.0.1 at 2023-05-28 08:39:12.786582

done 10.0.0.4 at 2023-05-28 08:39:14.795944
done 10.0.0.3 at 2023-05-28 08:39:14.796357
done 10.0.0.5 at 2023-05-28 08:39:14.796427

done 10.0.0.8 at 2023-05-28 08:39:16.807337
done 10.0.0.7 at 2023-05-28 08:39:16.807337
done 10.0.0.6 at 2023-05-28 08:39:16.807337

done 10.0.0.9 at 2023-05-28 08:39:18.817837
fykwrbwg

fykwrbwg2#

由于您可以检查有多少 * 活动线程 * 正在执行,您可以使用该信息来禁用创建新线程,如下所示:

def main():
    threads = threading.active_count()
    print(f"{threads=}") # show current number of threads for debugging
    if threads <= 1:
        # there is at most one thread (the main thread) running
        # so create the required threads
        for i in range(num_threads):
            thread = threading.Thread(target=deviceconnector, args=(i, enclosure_queue,), daemon=True)
            thread.start()
        print(f"{num_threads} created")

或者使用一个全局变量来存储线程是否被创建:

threads_created = False

def main():
    global threads_created
    if not threads_created:
        for i in range(num_threads):
            thread = threading.Thread(target=deviceconnector, args=(i, enclosure_queue,), daemon=True)
            thread.start()
        print(f"{num_threads} created, current number of threads is {threading.active_count()}")
        threads_created = True
    else:
        print("Threads already created")

相关问题