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(或多或少内部)头文件被重新定义pthread_create
为
# define pthread_create GC_pthread_create
实际上,Boehm 的 GC 需要的是在新线程调用堆栈的早期调用GC_register_my_threadGC_pthread_create
(并且正在这样做)。
过去,Glib (2.46) 提供了一种重新定义内存分配的方法,该方法已struct GMemVTable
被弃用 且不能再使用(我的 Debianlibglib2.02.0-dev
软件包是 version 2.50.3-2
)。有一个g_mem_gc_friendly
全局布尔值,但在查看 Glib 源代码时,它只是在释放内存区域之前清除它们。
最近的 GTK3(我的libgtk-3-dev
包有版本)正在使用(间接)通过Glib 线程函数3.22.11-1
创建线程(可能与 Dbus 相关,也可能与 GtkTextView 相关)。并且没有办法(除了通过修补源代码)被通知该线程的创建。我担心我会安装(例如使用)的任何 GTK 回调可能会从这些线程中调用。或者,如果我使用一些可能使用(或访问)某些-ed 缓冲区的方法对 GTK 小部件进行子类化,则可能会发生灾难。pthread_create
g_signal_connect
GC_malloc
另一方面,GTK 中有一个严格的编码规则,即所有 GTK 操作都应该只发生在主线程中。引用Gdk3 线程页面:
然而,GTK+不是线程安全的。您应该只使用线程中的 GTK+ 和 GDK
gtk_init()
并被gtk_main()
调用。这通常被称为“主线程”。
如果我自己遵循这条规则,我确信没有内部 GTK 代码会从某个非主线程调用我的回调(使用 Boehm GC)?
我的直觉是,如果GC_alloc
GTK 内部(不是直接由我的代码)从主线程外部调用,则会发生灾难(因为这些 GTK 内部线程尚未以 开始GC_pthread_create
;可能会调用我的一些代码,例如因为我正在继承一些现有的 GTK 小部件,或者因为我连接了一些 GTK 信号,即使我自己没有在主线程之外使用 GTK 和 Boehm GC 编写代码。)。
关键是 Boehm 的 GC 需要扫描可能使用它的每个线程中的每个堆栈。
FWIW,我在 GTK bugzilla 上报告了一个可能的错误#780815 。
一个典型的例子gtk+-3.22.11/examples/application9/
来自 GTK-3.22.11 tarball。由via非常间接地pthread_create
调用g_application_run
g_bus_get_sync