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

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

我只是遇到了一个不同的问题,我不知道为什么会发生这种情况:足够简单的模拟和渲染(6条5点线)会导致其中断。

前几步(我到处都看到大约60到400个)可以很好地渲染(不到一秒钟),直到一个步骤可以渲染两次。之后,它会忽略queue_draw,直到我在渲染窗口上拖动窗口,然后重新启动(直到再次中断)为止。

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

但是,这是一个完全不可接受的解决方案,因为不允许显示过程干扰正常的模拟线程(无延迟,无互斥等)。我需要一种使渲染线程“尽可能好”地执行的解决方案,因为它正在处理易失性数据。它并不一定要非常准确-我真的不在乎帧是否渲染有一点错误(帧i的一半,i + 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);


窗口是要绘制的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调用的锁定。

关于c - 当重复太快时,GTK3有时会忽略gtk_widget_queue_draw吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13593113/

10-10 02:30