【发布时间】:2016-01-18 17:42:49
【问题描述】:
在使用多处理和 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()
当尝试执行此 sn-p 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 秒
系统完整性保护:启用
崩溃的线程:0 调度队列:com.apple.main-thread
异常类型:EXC_BAD_ACCESS (SIGSEGV) 异常代码:0x0000000000000110 处的 KERN_INVALID_ADDRESS
0x110 附近的 VM 区域: --> __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 的子端崩溃
线程 0 崩溃::调度队列: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 或其他小部件的事实是可疑的。
【问题讨论】:
-
在我们提供帮助之前,我们必须知道为什么使用多处理而不是之后。在程序中,你期望 g.start() 做什么?您没有给它任何执行目标,它仅在 mainloop 完成后执行。以及如何使用这种技术执行多个进程,因此不需要多处理。旋转框只是一个条目,可以选择的值数量有限,因此不需要单独的过程。出现问题的原因似乎是技术不佳,如果这是真的,那么您必须获得更好的技术。
-
Doug Hellmann 的多处理基础知识pymotw.com/2/about.html 可能会有所帮助。
-
这个例子是显示问题的最小python程序,实际上我有9个进程通过ZMQ进行不同的通信。我这样做是为了克服 GIL 的限制。由于 Gui 是 Process 的子类,当我调用 start() 时,Process 安排一切以在新的 Process 中执行 Gui 的 run() 方法。有很多使用 target 的例子,但你也可以找到子类化的工作(在我看来更 OO)
-
我的疑惑来自于仅仅导入(而不是实际使用)Spinbox 会触发错误,提示该模块在 init 之外有直接指令,这看起来不是很pythonic。但这也发生在非常受限的情况下:Mac OSX 使用默认启动方法,使用 forserver 或 spawn 启动方法似乎可以工作,使用 linux 或 windows 似乎可以工作。
标签: python macos tkinter python-multiprocessing