退出时的加入过程- Tkinter +多处理



我正在编写一个GUI应用程序,其中有一个调用长任务的按钮。为了不冻结GUI,我使用python 3.3的multiprocessing模块将任务委托给另一个进程。然后我使用Pipe返回结果以供显示。

我希望应用程序不留下任何僵尸进程,即使在计算期间退出。因为我用的是mac电脑,这有两种方式:退出应用程序(Command+Q),或者直接关闭窗口。

下面是链接到GUI中的按钮的函数中的代码:

main_pipe,child_pipe=Pipe()
p=Process(target=worker,args=(child_pipe,data))
p.start()
try:
    while not main_pipe.poll():
        root.update()
    value_array=main_pipe.recv()
finally:
    p.join()

这不起作用,应用程序没有响应Command+q,关闭窗口会留下两个僵尸进程在运行(一个用于GUI,一个用于worker)。

如何使它在其他情况下工作?这是好的做法吗?这是一种更好、更蟒化的方法吗?

另外,在脚本的最后,我有这两行(exit()关闭应用程序,如果窗口关闭而不处理任何东西):

root.mainloop()
exit()

最后,update()和mainloop()有什么区别?是不是只有后者占用了程序,而update()没有?

好了,我终于解决了。虽然我不完全确定关于这个方法的python或副作用,如果有人需要它在这里。

我认为正确退出只能在mainloop()中发生,而不是在update()中发生,所以我写了两个函数,一个用于创建进程,一个用于检查它的输出,它们使用root.after()相互调用。我将进程守护标志设置为true,以确保适当的退出行为。下面是代码:

def process_start():
    global value_array
    global main_pipe

    main_pipe,child_pipe = Pipe()
    p=Process(target=worker,args=(child_pipe,data))
    p.daemon=True
    p.start()
    root.after(500,check_proc)
def check_proc():
    if not main_pipe.poll():
        root.after(500,check_proc)
    else:
        global value_array
        value_array=main_pipe.recv()

我仍然不确定是否需要p.join(),但恶魔的事情似乎绕过僵尸进程的问题

我之前遇到过类似的问题(除了我没有使用多进程)。经过将近一整天的研究,我得出了以下结论:

  1. mainloop和root.waitwindow将(有时)阻塞sys。退出信号,您的程序应在单击⌘Q后接收该信号。
  2. 您可以将⌘Q绑定到新功能,尽管您可能仍然会收到sys。退出信号
  3. 另一种方法(对我来说更可靠)是将tcl退出信号重新映射到另一个函数,而不是默认的函数。您可以使用以下命令重新映射退出事件(dock quit和⌘Q): root.createcommand('::tk::mac::Quit',function)
  4. 当试图退出软件时,使用sys.exit代替exit()quit()
  5. 您还可以使用root.wm_protocol("WM_DELETE_WINDOW", function)来定义当用户点击红色按钮时的行为。
  6. 你实际上可以通过标记root.overridedirect(1)使窗口的边界和三个默认按钮消失,从而迫使用户点击GUI上的按钮而不是关闭窗口。

相关内容

  • 没有找到相关文章

最新更新