2012-05-25 44 views
5

下面的代码不挂在linux在Python 3.2.2做任何事情:为什么tkinter不能很好地处理多处理?

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之前被导入该进程是分叉的,可以通过在函数f中导入tkinter来解决该问题,并且问题发生在Linux而不是Solaris中。

有谁知道到底是什么原因导致了这个问题,如果是故意的或最终会被修复?是否有任何解决方法,而不是在本地需要的地方导入tkinter(这看起来像不好的风格)?其他模块是否有与多处理相似的问题?

+1

-0。你知道这个问题。你知道一个错误报告已经提交。您知道解决方法。唯一的另一个主要问题是“其他模块是否有与多处理相似的问题?”,这似乎有点不确定。 –

+1

@StevenRumbalski:我不知道这个问题 - 我不知道tkinter在这里无法正常工作,或者为什么它依赖于平台。该错误报告是在3年前提交的,并且没有迹象表明任何人都知道为什么(或者在什么情况下)发生这种情况或者如何解决这个问题。也许我最后一个问题应该读到“是否有任何其他标准库模块在分支进程之前无法导入”,这有点更具体。 – James

回答

0

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

Tkinter.py匆匆一瞥后,它看起来像在启动过程可能是有用的,也许之前调用NoDefaultRoot功能。这一切都取决于连接到X服务器时。

否则在fork之后导入Tkinter似乎是要走的路。

0

截至2013年9月,还有一些关于错误报告的补充评论,可以更深入地了解实际问题。

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

基于上述,我猜像下面发生的事情:Tkinter的不是线程安全的,所以(无论何种原因)的Tkinter想知道哪个线程是主线程。 Tkinter假定Tkinter模块加载时的主线程也是程序执行的主线程。当你在加载Tkinter之后进行分叉或者多进程时,这个假设被打破了。 (例如,叉后,记住的主线程在父母,而不是孩子。)

相关问题