【问题标题】:Dispatch to GTK+'s Main Thread Synchronously同步调度到 GTK+ 的主线程
【发布时间】:2020-06-03 20:14:46
【问题描述】:

我正在将我现有的一些软件从 macOS 和 Windows 移植到 Linux。该软件的基础是在 GUI 后面运行的多线程服务器,可显示统计信息、生成特定事件的新窗口等。

在 macOS 上,我们有 DispatchQueue.main.sync。在 Windows / C# / WPF 上,我们有 Dispatcher.Invoke。我们专门在需要在更新 UI 线程时阻塞调用线程的情况下使用这些调用。 GTK+ 有类似的东西吗?

我一直使用gdk_thread_add_idle_full 来处理我不需要阻塞的代码的异步部分,但对于同步版本,它有点复杂。我当前的解决方案是一个包含 GMutex / GCond 对的简单对象。该对象在调用线程上是“可等待的”,在 UI 线程上是“可完成的”。将此对象传递给gdk_thread_add_idle_full 给了我想要的效果,但我很好奇是否有更简洁的选项。

服务器库是原样的,因此没有空间修改该代码以使其表现更好。我正在寻找工具包方面的解决方案。另外,GTK+ 的工作都是用 C 语言完成的。

【问题讨论】:

    标签: gtk gtk3 glib


    【解决方案1】:

    我认为没有更简洁的选择,并且使用 GMutex/GCond 对似乎可以合理地将您的工作线程与来自 UI 线程的回复同步。

    使用 GMutex/GCond 对的缺点是,这意味着您不能同时在工作线程上迭代 GMainContext。如果这不是您的应用程序的构造方式,那也没关系。

    如果是这样,那么您可能希望采用一种方法,在 gdk_threads_add_idle_full() 调用中将对工作线程的 GMainContext 的引用传递给 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 时继续进行其他有用的工作,而不是阻塞。但这可能与您的应用程序的构建方式无关。

    【讨论】:

    • 感谢您填写第二种方法。我最初的方法现在可以完成这项工作,但这对将来的使用很有帮助。我要包装的库是多线程的,所以我可以毫无问题地阻塞调用线程。
    猜你喜欢
    • 1970-01-01
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    • 2013-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多