c - 从 glib/gtk 中的单独线程发出信号
问题描述
我用 C 编写了一个 GTK3 应用程序。为了提高性能,我想将一些计算放在单独的线程中。目前我还没有决定如何准确地实现它。但我想我会选择一个GTask
我会触发在一个单独的线程中运行的。
我想在我的 GUI 上发出有关计算进度的某些状态更新。
他们按照我的想象:
我有一个带有触发线程/GTask 的 do_the_stuff_async() 函数的计算 GObject。理想情况下,我想连接到一个“进度改变”信号,它为我提供了可以在我的 GUI 上显示的当前状态。此外,一旦任务完成就触发一个事件会很棒,这似乎是可行的GTask
如何安全地从 GTask/GThread 向我的 GTK 主循环发出信号?
因为我还没有开始实现异步的东西: GTask 是适合这个的方式还是我应该使用完全不同的东西?
解决方案
AGTask
适合这个。
要在不同的线程中发出信号:
- 将主线程的存储在
GMainContext
某处,并将其GTask
作为任务数据传递给它。 - 当您想发出信号时,请创建一个
GSource
withg_idle_source_new()
,为其添加回调,并将其附加到GMainContext
主线程的。这将使回调在下一次主线程的上下文迭代时在主线程中被调用。 - 回调应
g_signal_emit()
酌情调用。
除非你想让GObject
你从线程安全地发出信号,否则你不应该将它传递给GTask
工作线程。我的一般建议是通过仅将不可变对象传入和传出工作线程来避免锁定。
请注意,您可以使用g_idle_add()
创建一个空闲GSource
并将其添加到全局默认值GMainContext
(GTK 在主线程中使用的那个)。然而,这使得使用GMainContext
不太明确,因此使代码更难维护。这不是我一般推荐的方法。
推荐阅读
- python - 如何设置我的 Django 函数以从按钮 onclick 在后台运行?
- vector - 如何在 Rust 中使用分隔符连接向量向量?
- arrays - 在 Julia 中按列堆叠数组
- algorithm - 将带有向量 v_i 和乘法 v_i * B 的树节点重构为一个矩阵乘法 A * B
- c# - 如何制作一个只能订阅一次的轻量级“重播”运算符?
- css - 我在 prestashop 上有 5 张不同的图片,但大约有 150.000 种产品,所以现在我有 22gb 的产品图片
- powerbi - Power BI:创建经理列的经理
- microcontroller - MSP430 停止响应高频查询
- python - 如何在pygame中让球移动而不是拉伸?
- android - 如何从资产重新创建房间数据库?