在Python中处理另一个线程中的信号

时间:2013-12-30 17:38:00

标签: python multithreading signals pygtk gtk3

我有一个运行在两个线程中的PyGtk(GTK + 3)应用程序:

  • 线程 A 是执行Gtk.main()的主应用程序线程,因此处理Gtk的事件/信号。
  • 线程 B 是一个PulseAudio事件线程,它以异步方式处理所有PA的内容。

在某些情况下,有必要通过线程 B 的回调处理事件,在Gtk对象中执行某些操作。 Python的问题在于,因为GIL一次只能运行一个线程,所以不可能直接更改任何与Gtk相关的东西 - 这会导致死锁。

它的一个解决方案可能是调用Gdk.threads_init()来允许Gtk解除GIL,但这似乎会导致竞争条件,显然Gtk不够线程安全。

我想要做的是'压扁'事件处理,以便线程B为线程 A 留下东西(事件/信号?)来拾取和处理。在此方案中,此操作不会阻止 B 线程。据我所知,Python的信令机制并非如此,因为它同步处理信号。

所以我的问题是:如何创建一种可以被Gtk的主循环拾取并由线程 A 代码处理的自定义事件?

1 个答案:

答案 0 :(得分:2)

Gtk不是线程安全的,你必须编写你的代码,以便它是线程安全的。

我不知道你正在使用什么版本的pygtk,但在GUI线程上排队操作的最简单方法是使用idle_add

http://www.pygtk.org/pygtk2reference/gobject-functions.html#function-gobject--idle-add

它在Gtk的主循环中排队一个函数,并将在它的线程上执行。

编辑:这是获取GUI线程上调用函数的最简单方法。如果你想做创建自定义gobject信号的工作,我相信(但不是100%肯定)将在GUI线程上调用信号处理程序。