同步发送到 GTK+ 的主线程
Dispatch to GTK+'s Main Thread Synchronously
我正在将我现有的一些软件从 macOS 和 Windows 移植到 Linux。该软件的基础是在 GUI 后面的多线程服务器 运行,它显示统计数据,在特定事件上生成新的 windows,等等
在 macOS 上,我们有 DispatchQueue.main.sync
。在 Windows / C# / WPF 上,我们有 Dispatcher.Invoke
。我们专门在更新 UI 线程时需要阻塞调用线程的情况下使用这些调用。 GTK+ 有类似的东西吗?
我一直在使用 gdk_thread_add_idle_full
作为我不需要阻塞的代码的异步部分,但对于同步版本,它有点复杂。我当前的解决方案是一个包含 GMutex
/ GCond
对的简单对象。该对象在调用线程上是 "waitable",在 UI 线程上是 "completeable"。将此对象传递给 gdk_thread_add_idle_full
可以达到我想要的效果,但我很好奇是否有更简洁的选项。
服务器库保持原样,因此没有空间修改该代码以使其表现更好。我正在寻找工具包方面的解决方案。此外,GTK+ 的工作全部在 C 中完成。
我认为没有更简洁的选项,使用 GMutex
/GCond
对似乎可以使工作线程与 UI 线程的回复同步。
使用 GMutex
/GCond
对的缺点是,这意味着您不能同时在工作线程上迭代 GMainContext
。如果您的应用程序不是这样构建的,那也没关系。
如果是,那么您可能希望采用一种方法,将对工作线程的 GMainContext
的引用传递给 gdk_threads_add_idle_full()
调用中的 UI 线程。一旦 UI 操作完成,UI 线程中的代码将在工作线程的 GMainContext
上调用 g_idle_source_new()
/g_source_attach()
以安排要执行的回调在工作线程中。此回调将更新状态以将操作标记为已完成并已返回。
在这种方法中,gdk_threads_add_idle_full()
和 g_idle_source_new()
/g_source_attach()
本质上都是从一个线程到另一个线程的消息传递函数。在您的方法中,GMutex
/GCond
充当同步栅栏。
第二种方法意味着您的工作线程可以在等待 UI 的同时继续执行其他有用的工作,而不是阻塞。但这可能与您的应用程序的构建方式无关。
我正在将我现有的一些软件从 macOS 和 Windows 移植到 Linux。该软件的基础是在 GUI 后面的多线程服务器 运行,它显示统计数据,在特定事件上生成新的 windows,等等
在 macOS 上,我们有 DispatchQueue.main.sync
。在 Windows / C# / WPF 上,我们有 Dispatcher.Invoke
。我们专门在更新 UI 线程时需要阻塞调用线程的情况下使用这些调用。 GTK+ 有类似的东西吗?
我一直在使用 gdk_thread_add_idle_full
作为我不需要阻塞的代码的异步部分,但对于同步版本,它有点复杂。我当前的解决方案是一个包含 GMutex
/ GCond
对的简单对象。该对象在调用线程上是 "waitable",在 UI 线程上是 "completeable"。将此对象传递给 gdk_thread_add_idle_full
可以达到我想要的效果,但我很好奇是否有更简洁的选项。
服务器库保持原样,因此没有空间修改该代码以使其表现更好。我正在寻找工具包方面的解决方案。此外,GTK+ 的工作全部在 C 中完成。
我认为没有更简洁的选项,使用 GMutex
/GCond
对似乎可以使工作线程与 UI 线程的回复同步。
使用 GMutex
/GCond
对的缺点是,这意味着您不能同时在工作线程上迭代 GMainContext
。如果您的应用程序不是这样构建的,那也没关系。
如果是,那么您可能希望采用一种方法,将对工作线程的 GMainContext
的引用传递给 gdk_threads_add_idle_full()
调用中的 UI 线程。一旦 UI 操作完成,UI 线程中的代码将在工作线程的 GMainContext
上调用 g_idle_source_new()
/g_source_attach()
以安排要执行的回调在工作线程中。此回调将更新状态以将操作标记为已完成并已返回。
在这种方法中,gdk_threads_add_idle_full()
和 g_idle_source_new()
/g_source_attach()
本质上都是从一个线程到另一个线程的消息传递函数。在您的方法中,GMutex
/GCond
充当同步栅栏。
第二种方法意味着您的工作线程可以在等待 UI 的同时继续执行其他有用的工作,而不是阻塞。但这可能与您的应用程序的构建方式无关。