GTK3有时会在重复太快时忽略gtk_widget_queue_draw?

时间:2012-11-27 21:09:34

标签: c gtk gtk3

我有一个应用程序可以进行一些模拟,并呈现结果。因为渲染有时可能非常慢,所以我将它分成另一个线程,主线程准备好后调用gtk_widget_queue_draw。如果它尚未完成绘制,则额外的请求将被丢弃(因为queue_draw仅使其无效,并且不可能“更多”无效)。

结果是,对于大型复杂系统,模拟最大化一个线程,并渲染最大化另一个线程,一切正常。

我遇到了一个不同的问题,我不明白为什么会发生这种情况:一个足够简单的模拟和渲染(6个5点线)会导致它崩溃。

前几个(我已经看到从60到400左右的所有地方)步骤渲染得很好(在几分之一秒内),直到一步渲染两次。之后,它会忽略queue_draw,直到我执行某些操作,例如在渲染窗口上拖动一个窗口,然后重新启动(直到它再次中断)。

如果我人为地减慢了请求(usleep(10000)已足够),则不会发生这种情况。

然而,这是一个完全不可接受的解决方案,因为不允许显示过程干扰正常的模拟线程(没有延迟,没有互斥等等)。我需要一个解决方案,使渲染线程尽可能“尽可能”,因为它使用的是易失性数据。它不一定非常准确 - 我真的不在乎框架是否有点错误(框架i的一半,i + 1的一半是好的),只要它渲染。

为什么会发生这种情况,我该如何解决?

2 个答案:

答案 0 :(得分:1)

你正处于竞争状态。

自GTK3.6 以来,您需要像这样致电gtk_widget_queue_draw

g_idle_add((GSourceFunc)gtk_widget_queue_draw,(void*)window);

或者像这样:

gdk_threads_add_idle((GSourceFunc)gtk_widget_queue_draw,(void*)window);

其中window是您要绘制的GtkWidget*

如果您不确定应用使用的库或代码是否使用已弃用的(自3.6之后的gdk_threads_add_idlegdk_threads_enter函数,请使用gdk_threads_leave

请参阅:https://developer.gnome.org/gdk3/stable/gdk3-Threads.html#gdk3-Threads.description

在GTK3.6之前,必须使用gdk_threads_entergdk_threads_leave来获取GTK呼叫的锁定。

答案 1 :(得分:0)

您是否使用gdk_threads_enter / gdk_threads_leave锁定了线程中的UI调用? 也许添加代码示例也会有所帮助......