是否有任何明确的文档说明idle_add()/ timeout_add()和/或它们安装的实际回调是否需要锁(任何类型)?
def work(*args):
# (1) gtk.gdk.threads_enter() #needed?
self.ui.change_some_label()
# (2) gtk.gdk.threads_leave() #?
# (3) gtk.gdk.threads_enter() #?
gobject.idle_add (work)
# (4) gtk.gdk.threads_leave() #?
def main():
gtk.gdk.threads_init()
#...
是否需要1 + 2和/或3 + 4?对于哪个pygtk版本 这适用吗?我的目标是单独2.12(在嵌入式 平台)和2.24(在桌面上)。线程是由于gstreamer。
对于底层的C函数g_idle_add(),g_timeout_add()我找到了一个gtk-app-devel discussion表示
如果你已经调用了gdk_threads_init,那么就是空闲和超时处理程序 将运行而不用 gdk线程锁定,您将不得不添加 gdk_threads_enter /如果你正在做gui的话就自己打电话。
...虽然这是从2004年开始的。我发现很难为GTK + -2或PyGTK找到明确的特定文档。
关于SO的许多答案支持通过idle_add调度GUI工作,没有任何锁/关键部分(例如GUI not updated from another thread when using PyGtk)
答案 0 :(得分:4)
调用g_idle_add()
和g_timeout_add()
不需要锁定:它们是线程安全的操作,并保证在当前正在旋转主循环的GMainContext
中调用回调。 / p>
您链接的文档说回调需要获取GDK主锁;回调由GLib调用,但锁定由GDK提供,因此您需要显式获取它以避免线程在回调发射期间中断。
因此,C API提供了gdk_threads_add_idle()
和gdk_threads_add_timeout()
函数(以及它们的full()变体),它们保证在保持GDK锁的情况下调用您的回调。 PyGTK不会包装这些函数,因为它还需要保存Python解释器锁;这意味着您需要记住在回调中自己致电gdk_threads_enter()
/ gdk_threads_leave()
。