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

在Python的另一个线程中处理信号,python,multithreading,signals,pygtk,gtk3,Python,Multithreading,Signals,Pygtk,Gtk3,我有一个PyGtk(GTK+3)应用程序,它在两个线程中运行: 线程A是一个主应用程序线程,它执行Gtk.main(),从而处理Gtk的事件/信号 ThreadB是一个PulseAudio事件线程,异步处理所有PA的内容 在某些情况下,需要使一个事件由来自线程B的回调处理,以便在Gtk对象中执行某些操作。Python的问题是,因为一次只能运行一个线程,所以不可能直接更改任何与Gtk相关的内容—这会导致死锁 一个解决方案可能是调用Gdk.threads_init()以允许为Gtk解除GIL,但

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

  • 线程A是一个主应用程序线程,它执行
    Gtk.main()
    ,从而处理Gtk的事件/信号
  • ThreadB是一个PulseAudio事件线程,异步处理所有PA的内容
在某些情况下,需要使一个事件由来自线程B的回调处理,以便在Gtk对象中执行某些操作。Python的问题是,因为一次只能运行一个线程,所以不可能直接更改任何与Gtk相关的内容—这会导致死锁

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

我想做的是“展平”事件处理,以便线程B为线程A留下一些(事件/信号?)来拾取和处理。在此场景中,线程B不会被此操作阻止。据我所知,Python的信令机制并非如此,因为它同步处理信号


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

Gtk不是线程安全的,您必须编写代码以使其线程安全

我不知道您使用的是哪个版本的pygtk,但在GUI线程上对操作排队的最简单方法是使用
idle\u add

它是Gtk主循环中的一个函数,将在其线程上执行


编辑:这只是在GUI线程上调用函数的最简单方法。如果您想创建自定义gobject信号,我相信(但不是100%确定)会在GUI线程上调用信号处理程序。

类似于:?@Bakuriu No,因为信号处理程序会在调用线程上运行。一个有效的解决方案是bj0提出的
GObject.idle\u add()
。谢谢@bj0,这个
idle\u add()
技巧很有效!我还检查了自定义信号的东西-不,它不会工作。信号处理程序在调用线程上运行。