PyGTK:带线程的gobject.idle_add()和timeout_add() [英] PyGTK: gobject.idle_add() and timeout_add() with threads

查看:837
本文介绍了PyGTK:带线程的gobject.idle_add()和timeout_add()的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



是否有任何明确的文档说明是否需要锁(任何类型)for idle_add()/ timeout_add()和/或它们安装的实际回调?

  def work(* args):
#(1)gtk.gdk.threads_enter()#需要?
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时不会从另一个线程更新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() p>

Is there any unambiguous documentation stating whether locks (of any kind) are needed or not for idle_add() / timeout_add() and/or the actual callbacks installed by them?

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()
  #...

Are 1+2 and/or 3+4 necessary? For which pygtk versions does this apply? I am targetting separately 2.12 (on an embedded platform) and 2.24 (on the desktop). Threads are due to gstreamer.

For the underlying C functions g_idle_add(), g_timeout_add() I found a gtk-app-devel discussion that states

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.

... though this is from 2004. I find it amazingly hard to locate clear, specific documentation for either GTK+-2 or for PyGTK.

Many answers on SO endorse scheduling GUI work via idle_add, with no locks / critical sections whatsoever (e.g. GUI not updated from another thread when using PyGtk)

解决方案

calling g_idle_add() and g_timeout_add() does not need locking: they are thread safe operations, and guarantee that the callback will be called in the GMainContext that is currently spinning the main loop.

the documentation you linked says that the callback will need to acquire the GDK master lock; the callback is invoked by GLib, but the lock is provided by GDK, hence you will need to acquire it explicitly to avoid threads interrupting during the callback emission.

for this reason, the C API provides the gdk_threads_add_idle() and gdk_threads_add_timeout() functions (and their full() variants), which guarantee to invoke your callback with the GDK lock held. PyGTK does not wrap those functions, because it would need to also hold the Python interpreter lock; this means that you will need to remember to call gdk_threads_enter()/gdk_threads_leave() yourself in the callback.

这篇关于PyGTK:带线程的gobject.idle_add()和timeout_add()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆