简体   繁体   English

Python GUI多处理并且仍然冻结

[英]Python GUI Multiprocessing and still freezing

I'm using TKinter to draw a GUI for a python program im making, and I have it updating at about 200ms, but when the program queries the data it locks the program because it takes a second to get the data. 我正在使用TKinter为我正在制作的python程序绘制GUI,并且我在大约200ms时更新它,但是当程序查询数据时它会锁定程序,因为它需要一秒钟来获取数据。 I tried to write it into multi processing so each query would be its own process and just share the info with global variables because my program is a real time program that uses wmi to get performance data. 我尝试将其写入多处理,因此每个查询都是它自己的进程,只是与全局变量共享信息,因为我的程序是一个使用wmi获取性能数据的实时程序。 At least thats what I have so far. 至少那是我到目前为止所拥有的。 Not the end goal just the start. 最终目标不仅仅是开始。 So if you could help me figure out why even with multiprocessing if it queries the info while I'm dragging the app across the screen it will freeze for a second. 所以,如果你能帮助我弄清楚为什么即使使用多处理,如果它在我在屏幕上拖动应用程序时查询信息它会冻结一秒钟。

import wmi
import time
import Tkinter as tk
from multiprocessing import cpu_count
import Image
from PIL import ImageTk
from Tkinter import Button, Label
import threading
from multiprocessing import Process, Value, Array

window = Tk();
global pct_in_use
global available_mbytes
global utilization
global hours_up
a= 0 
b=0    


def build_labels(gui, string):
    var = StringVar()
    label = Label( gui, textvariable=var, relief=RAISED )
    var.set(string)
    return label

def get_uptime():
    global hours_up
    c = wmi.WMI()
    secs_up = int([uptime.SystemUpTime for uptime in c.Win32_PerfFormattedData_PerfOS_System()][0])
    hours_up = secs_up / 3600
    return hours_up

def get_cpu():
    global utilization
    c = wmi.WMI()
    utilizations = [cpu.LoadPercentage for cpu in c.Win32_Processor()]
    utilization = int(sum(utilizations) / len(utilizations))  # avg all cores/processors
    return utilization

def get_mem_mbytes():
    global available_mbytes
    c = wmi.WMI()
    available_mbytes = int([mem.AvailableMBytes for mem in c.Win32_PerfFormattedData_PerfOS_Memory()][0])
    return available_mbytes

def get_mem_pct():
    global pct_in_use
    c = wmi.WMI()
    pct_in_use = int([mem.PercentCommittedBytesInUse for mem in c.Win32_PerfFormattedData_PerfOS_Memory()][0])
    return pct_in_use

def Draw():
    global mem_per_lb
    global cpu_lb
    global up_time_lb
    global mb_used_lb

    mem_pct = 0
    mem_per_lb = tk.Label(text='Memory % ' + str(mem_pct))
    mem_per_lb.place(x=10, y=10)

    cpu = 0
    cpu_lb = tk.Label(text='CPU % ' + str(cpu))
    cpu_lb.place(x=10, y=30)

    mem_pct = 0
    up_time_lb = tk.Label(text='UP Time % ' + str(mem_pct))
    up_time_lb.place(x=10, y=50)

    mem_pct = 0
    mb_used_lb = tk.Label(text='Memory MB ' + str(mem_pct))
    mb_used_lb.place(x=10, y=70)    


def Refresher():
    global mem_per_lb
    global cpu_lb
    global up_time_lb
    global mb_used_lb

    mem_pct = get_mem_pct()
    cpu = get_cpu()
    up_time = get_uptime()
    mbused = get_mem_mbytes()

    window.wm_title('Vision' + time.asctime())
    mem_per_lb.configure(text='Memory % ' + str(pct_in_use))
    cpu_lb.configure(text='CPU ' + str(utilization))
    up_time_lb.configure(text='UP Time ' + str(hours_up))
    mb_used_lb.configure(text='Memory MB ' + str(available_mbytes))

    window.after(200, Refresher) # every second...

def draw_window():               #creates a window 
    window.geometry('704x528+100+100')

    image = Image.open('bg.jpg')     #gets image (also changes image size)
    image = image.resize((704, 528))
    imageFinal = ImageTk.PhotoImage(image)
    label = Label(window, image = imageFinal)   #creates label for image on window 
    label.pack()
    label.place(x = a, y = b)      #sets location of label/image using variables 'a' and 'b'

    Draw()
    Refresher()
    window.mainloop()

up_time_p = Process(target=get_uptime())
cpu_p = Process(target=get_cpu())
mb_p = Process(target=get_mem_mbytes())
pct_p = Process(target=get_mem_pct())
win_p = Process(target=draw_window())

up_time_p.start()
mb_p.start()
pct_p.start()
cpu_p.start()
win_p.start()
up_time_p = Process(target=get_uptime())
cpu_p = Process(target=get_cpu())
mb_p = Process(target=get_mem_mbytes())
pct_p = Process(target=get_mem_pct())
win_p = Process(target=draw_window())

I don't think you're supposed to include parentheses when you supply targets to a process. 当您向流程提供目标时,我认为您不应该包括括号。 If you do that, the functions will execute in the main thread, and whatever those functions return will become the target. 如果这样做,函数将在主线程中执行,无论这些函数返回什么,都将成为目标。

up_time_p = Process(target=get_uptime)
cpu_p = Process(target=get_cpu)
mb_p = Process(target=get_mem_mbytes)
pct_p = Process(target=get_mem_pct)
win_p = Process(target=draw_window)

As per Kevin's answer, you're calling the functions when you create each process instance. 根据Kevin的回答,您在创建每个流程实例时调用这些函数。 So they are all actually running in the main process. 所以他们实际上都在主要流程中运行。

However, once you fix that problem your 'global' variables aren't going to work as you expect. 但是,一旦解决了这个问题,您的“全局”变量就无法按预期运行。 When a process is created it takes a COPY of the parent processes memory. 创建进程时,它会占用父进程内存的COPY。 Any changes to that memory are not shared between the processes. 对进程之间不共享对该内存的任何更改。

To achieve the result you want you'll have to use Python's threading library. 要获得结果,您需要使用Python的线程库。 Not the multiprocess library. 不是多进程库。

Threads share the same memory space as the parent process. 线程与父进程共享相同的内存空间。 Which can lead to its own problems. 这可能导致自己的问题。 Though in your case the global variables you're changing are just integer constants so it should be okay. 虽然在你的情况下,你正在改变的全局变量只是整数常量,所以它应该没问题。

from threading import Thread

data_funcs = (
    get_uptime, 
    get_cpu, 
    get_mem_mbytes, 
    get_mem_pct, 
    draw_window
)

threads = [Thread(target=f) for f in data_funcs]

for t in threads:
    t.start()

Is the general pattern you should use. 是您应该使用的一般模式。 You'll then have to figure out a way of killing those threads when you shut down the main process or it will hang. 然后,当您关闭主进程或者它将挂起时,您必须找出杀死这些线程的方法。

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

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