multithreading - 继续 OS X - 两个库调用系统函数

标签 multithreading macos user-interface go goroutine

我发现很难用或多或少的通用 UI 编写一些东西,至少对于 Mac 来说是这样。我的应用程序必须有 tray icon并能够显示system notifications

问题是 goroutines 本身。在 Mac 上对 UI 框架的任何调用都需要从主线程进行调用,或者至少以线程安全的方式进行。

当我已经在运行 UI(好吧,对于 GUI 应用程序这是必须的,不是吗?)并尝试显示通知时,问题就出现了。原因似乎是系统托盘包 Init 函数必须使用 runtime.LockOsThread 锁定到主线程并且永远不会释放它。然后,如果我尝试显示也需要 runtime.LockOsThread 的通知,则会导致以下错误:

2016-01-11 22:56:27.973 main[30162:4094392] *** Assertion failure in +[NSUndoManager _endTopLevelGroupings], /Library/Caches/com.apple.xbs/Sources/Foundation/Foundation-1256.1/Misc.subproj/NSUndoManager.m:359
2016-01-11 22:56:27.974 main[30162:4094392] +[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to invoke on the main thread.
2016-01-11 22:56:27.977 main[30162:4094392] (
    0   CoreFoundation                      0x00007fff8d42bae2 __exceptionPreprocess + 178
    1   libobjc.A.dylib                     0x00007fff8bb03f7e objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff8d42b8ba +[NSException raise:format:arguments:] + 106
    3   Foundation                          0x00007fff8cb4c88c -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 198
    4   Foundation                          0x00007fff8cad24c1 +[NSUndoManager(NSPrivate) _endTopLevelGroupings] + 170
    5   AppKit                              0x00007fff8514206a -[NSApplication run] + 844
    6   main                                0x0000000004166200 nativeLoop + 128
    7   main                                0x0000000004165bca _cgo_8c6479959095_Cfunc_nativeLoop + 26
    8   main                                0x000000000405a590 runtime.asmcgocall + 112
)
2016-01-11 22:56:27.977 main[30162:4094392] *** Assertion failure in +[NSUndoManager _endTopLevelGroupings], /Library/Caches/com.apple.xbs/Sources/Foundation/Foundation-1256.1/Misc.subproj/NSUndoManager.m:359
2016-01-11 22:56:27.978 main[30162:4094392] An uncaught exception was raised
2016-01-11 22:56:27.978 main[30162:4094392] +[NSUndoManager(NSInternal) _endTopLevelGroupings] is only safe to invoke on the main thread.

有解决办法吗?到目前为止,我所能想到的就是将 UI 和 Notifications 放入单独的二进制文件中,并使它们通过某种 IPC 与 main 进行通信。但我可能遗漏了一些东西。

最佳答案

由于对这个问题没有足够的关注,我决定发布我在尝试解决此问题时发现的自己的解决方案。这不会被标记为答案,因为其他人可能会提供更好的解决方案。

我已将其中一个 UI 进程(即使用系统托盘的部分)移动到另一个二进制文件中,并使用 cmd := exec.Command(...)cmd.Start 调用它() 然后我通过管道传输 stdinstdout 并通过它们与这个子进程通信。

示例代码可以在 Github 上找到. 警告 这个要点中有一个错误,子进程退出后主进程将开始消耗 CPU 周期。请自行修复。

我不想使用 RPC 的原因是因为这对于我想要实现的目标来说会变得有点过于复杂,并且没有提供进行双向通信的简单方法。

关于multithreading - 继续 OS X - 两个库调用系统函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34724912/

相关文章:

java - 当我有套接字和线程时如何彻底停止tomcat

Java:同步列表

macos - 删除关闭 (CMD+W) 菜单栏按钮不起作用 SwiftUI

html - 用于 C++ 游戏的精美交互式 GUI

java - C# 和 Java 中的 GUI 组件是否分别由单独的线程运行?

javascript - 如何控制td中包含更多字符(包括字母和数值)的文本?

java - 这个多线程 Java 代码是如何工作的?

c# - 在 C# 中停止线程

macos - 如何使用 SwiftUI 构建 AppKit TableView ?

c++ - Mac错误: Undefined symbols for architecture x86_64