以下代码挂起而没有在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
之外还有其他解决办法吗(这看起来很糟糕)?其他任何模块都有与多处理类似的问题吗?
答案 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之后,记住的主线程位于父级,而不是子级。)