在 glib/gtk 中从单独的线程发出信号

Emit signal from separate thread in glib/gtk

我用 C 编写了一个 GTK3 应用程序。为了提高性能,我想将一些计算放在单独的线程中。目前我还没有决定如何准确地实施它。但我想我会使用 GTask,我将在单独的线程中触发 运行。

我想在我的 GUI 上发布有关计算进度的某些状态更新。

他们是我想象的样子:

我有一个计算 GObject,它带有触发 thread/GTask 的 do_the_stuff_async() 函数。理想情况下,我想连接到一个 'progress-changed' 信号,它给我可以在我的 GUI 上显示的当前状态。一旦任务完成就触发一个事件也很好,这似乎可以用 GTask

如何安全地从 GTask/GThread 向我的 GTK 主循环发出信号?

因为我还没有开始实现异步的东西:GTask 是适合这个的方法还是我应该使用完全不同的东西?

一个GTask适合这个

要在不同的线程中发出信号:

  1. 将主线程的GMainContext存放在某处,作为任务数据传入GTask
  2. 当你想发出一个信号时,用g_idle_source_new()创建一个GSource,为它添加一个回调,并将它附加到主线程的GMainContext。这将使主线程的上下文下次迭代时在主线程中调用回调。
  3. 回调应适当调用 g_signal_emit()

除非你想让 GObject 从线程发出信号是安全的,否则你不应该将它传递给 GTask 工作线程。我的一般建议是通过仅将不可变对象传入和传出工作线程来避免锁定。

请注意,您可以使用 g_idle_add() 创建一个空闲 GSource 并将其添加到全局默认 GMainContext (GTK 在主线程中使用的那个)。然而,这使得 GMainContext 的使用不那么明确,因此使代码更难维护。这不是我一般推荐的方法。