multithreading - PyGTK:gobject.idle_add() 和 timeout_add() 与线程

标签 multithreading user-interface thread-safety gtk pygtk

是否有任何明确的文档说明 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/

相关文章:

python - 我怎样才能让这个计时器永远运行?

java - 使用Java Swing GUI制作石头、剪刀、布、蜥蜴、斯波克

ruby-on-rails - Rails 3 ActiveRecord .skip_callback 线程安全

regex - 像 "regexec"这样的正则表达式函数在 libc 版本 2.2.5 中是线程安全的吗?

java - 从 java Grpc 服务器调试线程转储?

c++ - boost::thread 在线程之间传递数据

java - 由于空指针异常,应用程序崩溃

c++ - 使用 QML 的普通(桌面)用户界面控件?

java - System.out.println() 从数据库到表

multithreading - 无状态 session 线程安全吗?