48

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_createg_signal_connectGC_malloc

另一方面,GTK 中有一个严格的编码规则,即所有 GTK 操作都应该只发生在主线程中。引用Gdk3 线程页面:

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

如果我自己遵循这条规则,我确信没有内部 GTK 代码会从某个非主线程调用我的回调(使用 Boehm GC)?

我的直觉是,如果GC_allocGTK 内部(不是直接由我的代码)从主线程外部调用,则会发生灾难(因为这些 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_rung_bus_get_sync

4

0 回答 0