【发布时间】:2011-09-04 22:29:20
【问题描述】:
我在 Mac OS X (10.6.7) 下遇到了与 GUI/线程相关的问题。 我正在使用 wxWidgets 框架(版本 2.9.1),在我的例子中它依赖于 Cocoa。应用设计是这样的:
- 线程 #1(又名“主线程”):进入 main(),解析开关,并在必要时启动另一个线程(使用 POSIX 原语)。
- 线程 #2(又名“GUI 线程”):使用 wxEntry 初始化 wxWidgets 并显示 GUI。
与大多数其他 GUI 框架一样,Cocoa 不是线程安全的,因此我们确保在线程 #2 中执行所有 GUI 调用,并在需要时传递消息。 然而,在这种特殊情况下,在初始化期间(从 NSUndoManager 更准确地说)从 Cocoa 内部提出了一个断言,本质上说“在主线程之外使用我是不安全的”。即使线程 #2 是 主线程,就任何与 GUI 相关的内容而言。
嗯,NSUndoManager 必须有办法找出它是否在主线程之外运行(可能使用 NSThread::isMainThread())。所以我的问题是:是否有可能以此欺骗 NSUndoManager (以及一般的 Cocoa)?更好的是,声明线程#2 为“主线程”,线程#1 成为次要线程?基本上,我需要一个 API 调用,例如“使调用线程成为主线程”。只要在 OS X 10.5 上也能正常工作,无证巫术和 Objective C++ 都可以。
P.P.现在的代码可以在 Windows/Linux/MacOSX+Carbon 下完美运行。此外,重新设计它以更改线程结构将是一个巨大的痛苦。
【问题讨论】:
-
线程#1 在应用程序生命周期内做什么?
-
[NSThread isMultiThreaded]是否返回YES?您需要使用 NSThread 为 Cocoa 生成至少一个线程以启用多线程支持。 -
为什么不使用主线程进行 GUI 和其他线程的其余工作?
-
@John,线程#1 产生了一些其他线程,并在某种事件循环中等待事件。它基本上组织了一切。 @LaC,感谢您的指点,我会检查一下。 @wilx,正如我所说,我可以将主线程用于 GUI,但这需要重新设计,因为在我们的例子中,GUI 是可选的 - 它可能不需要,但应用程序可能仍需要执行所有其他工作。本质上,GUI 仅用于可视化正在完成的工作。
-
我不知道造成这种情况的实现细节是什么,但我记得有一次做你正在做的事情(一个线程中的 GUI 和事件循环,而不是调用的线程
main在 Mac OS 上)和系统库会变得非常混乱。例如,它会在第一次与 GUI 相关的调用时崩溃或死锁。我会想办法让自己从main打来电话。如果您的应用程序设计得很好,我不确定为什么它会是一个“巨大的痛苦”,所以我鼓励您更加努力地思考它。结果会比热补丁 Cocoa 或一些这样的黑客更好。
标签: c++ multithreading cocoa macos wxwidgets