为什么tkinter不能很好地处理多处理?

时间:2012-05-25 13:54:01

标签: python tkinter multiprocessing

以下代码挂起而没有在linux中的python 3.2.2中做任何事情:

import tkinter
from multiprocessing import Process

def f():
    root = tkinter.Tk()
    label = tkinter.Label(root)
    label.pack()
    root.mainloop()

p = Process(target=f)
p.start()

我发现的关于此问题的唯一信息是issue 5527,其中注意到问题是在进程分叉之前导入tkinter,可以通过导入{修复}函数tkinter内部{1}},问题出现在Linux而不是Solaris。

有谁知道究竟是什么导致了这个问题,如果是有意的还是最终会被修复?除了在我需要它的地方导入f之外还有其他解决办法吗(这看起来很糟糕)?其他任何模块都有与多处理类似的问题吗?

2 个答案:

答案 0 :(得分:0)

我怀疑这个问题与X服务器(通常是套接字)的连接有关。如果在进程为fork()之前创建了此选项,则子进程将继承此连接。但如果它试图使用它,那么X服务器会感到困惑。

在粗略看一下Tkinter.py之后,看起来可能在启动可能的过程之前调用NoDefaultRoot函数。这完全取决于何时与X服务器的连接。

否则在fork之后导入Tkinter似乎是可行的方法。

答案 1 :(得分:0)

截至2013年9月,对错误报告有一些额外的评论,可以更深入地了解实际问题。

http://bugs.python.org/issue5527#msg194848
http://bugs.python.org/issue5527#msg195480

基于以上所述,我猜测会发生以下情况:Tkinter不是线程安全的,所以(无论出于何种原因)Tkinter想要知道哪个线程是主线程。 Tkinter假设加载Tkinter模块时的主线程也将是程序执行的主线程。在加载Tkinter后进行fork或multiprocess时,这个假设就会被破坏。 (例如,在fork之后,记住的主线程位于父级,而不是子级。)