Tkinter Spinbox和多处理导致mac SEGFAULT

时间:2016-01-18 17:42:50

标签: python macos tkinter python-multiprocessing

使用多处理和tkinter时,我的应用程序在OSX上失败了。最小的例子很简单如下:

import multiprocessing
from tkinter import Spinbox #Delete this line and it works

class Gui(multiprocessing.Process):

    def run(self):
        self.start_window()
        self.root.mainloop()

    def start_window(self):
        from tkinter import Tk
        self.root = Tk()
        self.root.title('Test')

g = Gui()
g.start()

尝试执行此代码段时,mac失败并显示以下报告:

  

流程:Python [1453]   路径:> /Library/Frameworks/Python.framework/Versions/3.4/Resources/Python.app/Contents/MacOS/Python   标识符:Python   版本:3.4.4(3.4.4)   代码类型:X86-64(原生)   父进程:Python [1452]   负责人:终点站[395]   用户ID:501

     

日期/时间:2016-01-18 18:33:23.281 +0100   操作系统版本:Mac OS X 10.11.2(15C50)   报告版本:11   匿名UUID:49081BD5-7C1E-52F6-E5D9-F9F41BA8DFE5

     

启动后的时间清醒:6200秒

     

系统完整性保护:已启用

     

Crashed Thread:0 Dispatch queue:com.apple.main-thread

     

异常类型:EXC_BAD_ACCESS(SIGSEGV)   例外代码:KERN_INVALID_ADDRESS位于0x0000000000000110

     

VM区域接近0x110:    - >       __TEXT 0000000100000000-0000000100001000 [4K] r-x / rwx SM = COW /Library/Frameworks/Python.framework/Versions/3.4/Resources/Python.app/Contents/MacOS/Python

     

特定应用信息:    *多线程进程分叉*   在fork pre-exec的孩子一边坠毁

     

Thread 0 Crashed :: Dispatch queue:com.apple.main-thread   0 libdispatch.dylib 0x00007fff99f0fd69 _dispatch_async_f_slow + 391

     

1 libxpc.dylib 0x00007fff8fb8daa0 xpc_connection_resume + 192

     

2 com.apple.CoreFoundation 0x00007fff9bbb69d1 _CFPrefsWithDaemonConnection + 353

删除Spinbox导入(代码中未使用)会使一切运行。 python 3.4.4和2.7上出现了同样的问题(将tkinter更改为Tkinter)

删除多处理模块并使所有内容在同一进程上运行也会使问题消失。

我的猜测是我违反了某些Tk / Tcl限制,但是我还没有找到任何关于此事的文档,而且这只发生在Spinbox而不是Entry或其他小部件很可疑

2 个答案:

答案 0 :(得分:1)

我设法使它工作,由于某种原因,tkinter想要在它执行的同一个线程/进程中导入。

当扩展multiprocess.Proccess时,新的进程代码在run()方法内部,init在父进程上执行。因此,在run方法上更改要在本地完成的所有导入可以解决问题。

示例代码如下所示:

import multiprocessing

class Gui(multiprocessing.Process):

    def run(self):
        from tkinter import Spinbox # or Tk, or * ....
        self.start_window()
        self.root.mainloop()

    def start_window(self):
        from tkinter import Tk
        self.root = Tk()
        self.root.title('Test')

g = Gui()
g.start()

现在我的应用程序适用于Windows,Linux和Mac。

答案 1 :(得分:0)

当我从IDLE编辑器运行代码时,在Windows上,没有错误,但也没有tk框,只有'>>>'壳牌提示。当我将代码的结尾放在if name 子句下时,具体在multiprocessing doc

g.start()

出现一个tk框。只有=COUNTIFS(Sorted!A:A, "HatType", Sorted!D:D, "PantType", Sorted!C:C, ">="&DATE(YEAR(TODAY()), MONTH(TODAY()), 1), Sorted!C:C, "<"&DATE(YEAR(TODAY()), MONTH(TODAY())+1, 1)) =SUMPRODUCT((Sorted!A:A="HatType")*(Sorted!D:D="PantType")* (MONTH(Sorted!C:C)=MONTH(TODAY()))*(YEAR(Sorted!C:C)=YEAR(TODAY()))) 如此受保护,情况也是如此。在Mac上试用一个或两个版本。我不知道这是否是OSX上的唯一问题,但它至少会让你从其他系统上运行的东西开始。