最近GTK 3.22仍然Boehm GC友好(线程问题)?

Boehm的保守垃圾收集器非常有用(比如Bigloo正在使用它, Guile使用类似的东西等等),特别是在Linux上(这是我唯一关心的操作系统;我使用的是Debian / Sid / x86 -64,如果是这样的话, libgc-dev包是版本1:7.4.2-8所以Boehm GC是7.4.2)。

但是, Boehm的GC需要知道使用它的每个线程。 其gc_pthreads_redirects.h (或多或less的内部)头文件重新定义pthread_create

 # define pthread_create GC_pthread_create 

实际上,Boehm的GC需要在新的线程调用堆栈中调用GC_pthread_createGC_pthread_create正在这样做)。

过去,Glib(2.46)提供了一种使用struct GMemVTable重新定义内存分配的方法, 该方法废弃 ,不能再使用 (我的Debian的libglib2.02.0-dev软件包版本为2.50.3-2 )。 有一个g_mem_gc_friendly全局布尔值,但是当查看Glib源代码时,它只是清除内存区域,然后释放它们。

最近的GTK3(我的libgtk-3-dev软件包版本为3.22.11-1 )正在创build线程(对于可能与Dbus相关的东西,也许还涉及到GtkTextView …),通过Glib线程函数使用(间接) pthread_create 。 没有办法(除了修补源代码)被通知该线程创build。 我比任何GTKcallback恐怕会安装(例如使用g_signal_connect )可能会从这些线程调用。 或者,如果我用一些可能使用(或访问)一些GC_malloc -ed缓冲区的方法来GC_malloc一个GTK小部件,那么这可能是一场灾难。

另一方面,GTK中有一个强大的编码规则,所有的GTK操作只能在主线程中进行。 引用Gdk3主题页:

然而, GTK + 不是线程安全的 。 你应该只使用GTK +和GDK从线程gtk_init()gtk_main()被调用。 这通常被称为“主线程”。

如果我自己遵循这个规则,我相信没有内部的GTK代码会从一些非主线程中调用我的callback(使用Boehm GC)?

我的直觉是,如果有GC_alloc从GTK内部(不是直接由我的代码)从主线程外部调用,将发生灾难(因为这些GTK内部线程尚未启动GC_pthread_create ;可能会调用我的一些代码,例如,因为我是inheritance了一些现有的GTK小部件,或者是因为我连接了一些GTK信号,即使我自己没有在主线程之外使用GTK和Boehm GC编写代码)。

重点是Boehm的GC需要扫描每个线程中的每个堆栈,可能使用它。

FWIW,我在GTK bugzilla上报告了一个可能的bug#780815 。

一个典型的例子是GTK-3.22.11 tarball中的gtk+-3.22.11/examples/application9/pthread_create g_application_run非常间接地通过g_application_run g_bus_get_sync

GTK +不是用垃圾回收器来编写的。 您将不得不修改GDK及其构建的库,以调用GC_ *分配函数以使其工作。 简单地通知多余的GLib线程GC似乎并不是一个解决方案。

也就是说,如果GTK +和它所使用的库有一个不同于Boehm GC的堆,那么这可能不是问题。 您的应用程序可能并不完全没有内存泄漏和其他问题,但至少您编写的所有代码都将正确GC'd。