【问题标题】:Progress bar lagging with computationally intensive function on separate thread tkinter进度条滞后于单独线程 tkinter 上的计算密集型函数
【发布时间】:2020-05-09 01:37:45
【问题描述】:

我正在尝试实现一个 GUI 来帮助一些同事进行图像处理,但我遇到了 Tkinter (ttk) 进度条的问题,当我在另一个线程中执行工作时,它一直滞后。

基本上,我想让进度条在不确定模式下运行并来回弹跳,作为一种视觉确认事情仍在进行中(就像 Windows 中的“工作”圈)。

我是这样设置的:

# Frame/root set up (etc.) above here...

pbv = IntVar()
progressBar = ttk.Progressbar(consoleFrame, orient="horizontal", length=100, variable=pbv, mode="indeterminate")
progressBar.grid(column=1, row=1, sticky=N)
progressBar.start()

root.mainloop()

它会按预期反弹,在主线程上运行良好。到目前为止还不错。

然后,我初始化一个单独的线程并运行一个计算量很大的函数。

externalFunctionThread = threading.Thread(target=expensiveFunctionThread, args=[foo])
externalFunctionThread.deamon = True
externalFunctionThread.start()

有一些功能:

def expensiveFunctionThread(foo):
   for i in range(a_few_iterations):
      superDuperExpensiveFunction(i, foo)
      # Note: Were I to comment this out and replace it with a time.sleep(n), the bar would progress normally
      # Even a for loop that prints numbers up to some large integer would not cause lag

就上下文而言,superDuperExpensiveFunction 是对 pyradiomics 函数的调用,该函数从某个图像生成许多纹理特征。

最终发生的情况是,bar 将严重滞后,在 superDuperExpensiveFunction 运行时经常锁定(不移动),仅在每次迭代后移动。超级duper-expensive函数线程一旦结束就会恢复正常。

我查看了此板上的其他线程(How to connect a progress bar to a function?Tkinter: How to use threads to preventing main event loop from "freezing"ttk progress bar freezing 等),但它们都没有帮助,因为它们担心进度条在开始时冻结,而不是滞后于其更新。最后一个不起作用(包括 progressBar.update()/progressBar.update_idletasks() 什么都不做)。我担心它与 Python 如何处理线程有关(因为最终只有 1 个“真正的”线程可以一次工作,而 Python 必须循环允许哪个线程工作(GIL 或其他什么? ))。

无论如何,有解决方法吗?为什么会发生这种情况?

【问题讨论】:

标签: python-3.x tkinter progress-bar python-multithreading ttk


【解决方案1】:

好的,所以在做了一些研究后,我发现 pyradiomics 有一个标志,禁止这种快速任务切换,因此线程不是一个可行的解决方案。为了解决这个问题,按照 furas 的建议,我实现了多处理(实际上是池化!)。这不仅让我可以毫无延迟地运行进度条,还可以跨内核划分计算,大大加快了我的实现速度。语法与线程的语法非常相似,除了一个主要的例外,在我弄明白之前给我带来了很多悲伤。变量不被子进程继承!因此,如果我想从 Entry 或其他东西中获取值,我必须将其显式传递给子进程。过去,真的没有那么多变化。而不是线程只使用关联的进程事物(进程而不是线程,multiprocessing.Queue 而不是队列)。没有延迟,效率更高!

【讨论】:

    猜你喜欢
    • 2013-07-12
    • 1970-01-01
    • 2020-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-05
    • 1970-01-01
    相关资源
    最近更新 更多