多处理冻结/挂起Python中的tkinter GUI

2024-09-28 23:41:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个GUI类,它只包含tkinter小部件的实例,而不是tkinter的子类。这个GUI类还有一个数据处理对象的实例,它调用一个需要很长时间才能执行的成员函数。为了防止GUI冻结并更新进度条,我使用了多处理。在

outqueue = mp.Queue()
objqueue = mp.Queue()
progqueue = mp.Queue()
try:
     process = mp.Process(target=self.vromad.extractPlayers_mp,args=[outqueue, objqueue, progqueue])
     process2 = mp.Process(target=self.vromad.extractPlayers)
     process2.daemon = True
     process.daemon = True
     process.start()
     process2.start()
     print("started process")
     self.frame.after(500, self.updateBar, progqueue)
     print("bar should have started")
except:
     self.exceptionPopUp(traceback.format_exc())
     xtractStatus = -1
print("already here") 

这是行为真正有趣的地方。我运行与第一个进程相同的第二个进程,以检查多进程是否有任何阻塞。不,在两个任务完成之前都会打印“已启动进程”。实际上,通过添加process2.start()可以使CPU使用率翻倍。此外,“bar should started”和“already here”将在bar实际更新之前打印出来。事实上,回调self.updateBar打印“已在此处”后的输出

实际上,当代码继续过度运行时,所有的GUI事件都被推迟到所有的空闲状态。看起来确实是这样,因为在进程完成之前,条不会更新,而且整个窗口都会冻结。我试过延迟时间自帧后短至10ms,长至1000ms,行为无变化。这是因为进程以某种方式获得了tkinter的某些属性,它阻止了tkinter通过其事件循环?切换到线程有帮助吗?在


Tags: 实例selfqueue进程tkinterbarguimp
1条回答
网友
1楼 · 发布于 2024-09-28 23:41:02

我发现出了什么问题。当处理按钮按下的命令正在生成一个新进程来执行该工作时,它正在使用somequeue.get()等待工作完成。由于命令处理与tkinter的mainloop()在同一个线程中运行,mainloop()事件被阻塞,导致这里看到的问题。通过移动somequeue.get()编写另一个函数,直到所有的工作都完成。此函数还可以更新进度条,同时检查队列中是否有显示所有工作已完成的sentinel值。在

这就是重点。只有当所有的工作都完成时,该功能块才。在

相关问题 更多 >