问题描述
我正在构建一个 gtk3 应用程序,并试图找出在更新 UI 的 GTask
完成时避免竞争条件。
由于 data_acq()
调用的函数 (GTask
) 长时间运行,我有一个更新的进度条(通过 gdk_threads_add_timeout(progressBar_timeout_cb)
),但在 {{1 }} 我使用 data_acq()
将进度条设置为 100%。问题在于 gdk_threads_add_idle(progressBar_complete,params)
的最后一步是自动调用 GTask
,它释放指向进度条的指针,当 free_data_acq_data(params)
触发时会导致段错误,如果它发生 在 progressBar_complete(params)
发生之后。
这个问题可能完全是由于我滥用指针(或其他一些菜鸟错误),但我承认我没有看到如何以保证 1) 数据被释放的方式传递数据使用后和 2) 不会过早释放。请注意,任务可能被取消,因此我不想释放 free_data_acq_data(params)
中的内存。
所以我的问题是:在这种情况下是否有更好的方法来避免竞争条件(或者是否有另一种方法来构建代码以避免此问题)?或者是否有一种机制可以检查 progressBar_complete()
函数是否已完成,以便我可以告诉内存释放函数等待 gdk_threads_add_idle()
完成?
我尝试使用全局来跟踪 idle
是否已运行,但我无法让它与 progressBar_complete
完美配合,因为这意味着 GTask
从未完成(因为线程从未被放弃给 free_data_acq_data
来更新全局)。
为了具体起见,这里是一些示例代码:
progressBar_complete
解决方法
如果您需要从 UI 线程访问进度条指针,那么我建议不要在工作线程中释放它。也许当任务完成或取消时,您可以使用 gdk_threads_add_idle()
来排队另一个函数,该函数将释放 UI 端使用的资源,例如 dataAcqParams
,而不是在工作线程中释放它?>