我有一个应用程序,可以进行一些模拟,并呈现结果。因为渲染有时可能很慢,所以我将其分成另一个线程,一旦准备好,主线程就会调用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_idle
和gdk_threads_enter
函数,请使用gdk_threads_leave
。参见:https://developer.gnome.org/gdk3/stable/gdk3-Threads.html#gdk3-Threads.description
在GTK3.6之前,必须使用
gdk_threads_enter
和gdk_threads_leave
来获取GTK调用的锁定。关于c - 当重复太快时,GTK3有时会忽略gtk_widget_queue_draw吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/13593113/