是否有任何明确的文档说明 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说明
If you have called gdk_threads_init then idle and timeout handlers will be run without the gdk thread lock and you will have to add gdk_threads_enter/leave calls yourself if you are doing gui stuff.
...虽然这是从 2004 年开始的。我发现很难找到 GTK+-2 或 PyGTK 的清晰、具体的文档。
SO上的许多答案都支持通过idle_add调度GUI工作,没有任何锁/关键部分(例如GUI not updated from another thread when using PyGtk)
最佳答案
调用g_idle_add()
和 g_timeout_add()
不需要锁定:它们是线程安全的操作,并保证回调将在 GMainContext
中调用目前正在旋转主循环。
您链接的文档说回调需要获取 GDK 主锁;回调由 GLib 调用,但锁由 GDK 提供,因此您需要显式获取它以避免在回调发射期间线程中断。
因此,C API 提供了 gdk_threads_add_idle()
和 gdk_threads_add_timeout()
函数(及其 full() 变体),它们保证在持有 GDK 锁的情况下调用您的回调。 PyGTK 不包装这些函数,因为它还需要持有 Python 解释器锁;这意味着您需要记得调用 gdk_threads_enter()
/gdk_threads_leave()
自己在回调中。
关于multithreading - PyGTK:gobject.idle_add() 和 timeout_add() 与线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20291653/