我正在创建一个脚本来检查我的一些计算机的状态,但注意到随着时间的推移,Tkinter窗口正在积累越来越多的资源。有什么方法可以解决这个问题吗?
import subprocess
import time
import tkinter as tk
import threading
import gc
ip_addresses = ["192.168.1.83", "192.168.1.93", "192.168.1.93", "192.168.1.92", "192.168.1.95", "192.168.1.103", "192.168.1.105"]
i= 0
if i == 0:
root = tk.Tk()
root.title("Online")
root.geometry("500x300")
i+1
label_texts = [f"{ip_address} -> unknown" for ip_address in ip_addresses]
labels = [tk.Label(root, text=label_text, font=("Arial", 16), fg="#FF0000") for label_text in label_texts]
for i, label in enumerate(labels):
label.pack(padx=10, pady=5)
def check_ip_status(ip_address, label):
try:
subprocess.check_output(f"ping {ip_address} -n 1", shell=True, timeout=5)
label.config(text=f"{ip_address} -> online", fg="#00FF00") # Green
except subprocess.CalledProcessError:
label.config(text=f"{ip_address} -> offline", fg="#FF0000") # Red
except subprocess.TimeoutExpired:
label.config(text=f"{ip_address} -> offline (timeout)", fg="#FFA500") # Orange
def check_all_ip_statuses():
processes = []
for i, ip_address in enumerate(ip_addresses):
label = labels[i]
process = subprocess.Popen(f"ping {ip_address} -t", shell=True, stdout=subprocess.DEVNULL)
processes.append(process)
thread = threading.Thread(target=check_ip_status, args=(ip_address, label))
thread.start()
root.after(5000, check_all_ip_statuses)
gc.collect()
# Close all subprocesses
for process in processes:
process.kill()
process.communicate()
check_all_ip_statuses()
root.mainloop()
我试过强制垃圾收集器,杀死所有进程,并清除标签,但没有什么能阻止tkinter囤积越来越多的内存
------------更新----------
我已经将子进程调用更改为pythonping
import pythonping
import time
import tkinter as tk
import threading
import gc
ip_addresses = ["192.168.1.83", "192.168.1.85", "192.168.1.93", "192.168.1.92", "192.168.1.95", "192.168.1.103", "192.168.1.105"]
i= 0
if i == 0:
root = tk.Tk()
root.title("Online")
root.geometry("500x300")
i+1
def create_labels():
global labels
labels = [tk.Label(root, text=f"{ip_address} -> unknown", font=("Arial", 16), fg="#FF0000") for ip_address in ip_addresses]
for label in labels:
label.pack(padx=10, pady=5)
def check_ip_status(ip_address, label):
response = pythonping.ping(ip_address, count=1, timeout=5)
if response.success():
label.config(text=f"{ip_address} -> online", fg="#00FF00") # Green
else:
label.config(text=f"{ip_address} -> offline", fg="#FF0000") # Red
def check_all_ip_statuses():
for i, ip_address in enumerate(ip_addresses):
label = labels[i]
thread = threading.Thread(target=check_ip_status, args=(ip_address, label))
thread.start()
gc.collect()
root.after(1000, check_all_ip_statuses)
create_labels()
check_all_ip_statuses()
root.mainloop()
1条答案
按热度按时间ssm49v7z1#
当你一遍又一遍地启动你的线程时,每隔一秒,你就会用新的线程填满你的内存,即使当前的线程还没有完成。
这不是垃圾收集的问题,而是等待任务完成,然后再重新启动它们。
所以我把
check_all_ip_statuses()
改成这样:你应该以守护进程的形式运行线程,否则当你退出应用程序时会出错。现在你可以看到,线程只有在最后一个线程完成ping并准备好进行下一轮之后才重新启动。这将防止你的ram被填满。
**注意:**这可能会减慢你的ping间隔为您添加到列表中的每个ip.但我没有测试这个.
在你的代码中还有一些我不明白的地方,我把它清理了一下。我希望这没问题。
以下是全部来源: