Boehm's conservative garbage collector非常有用(例如,Bigloo正在使用它,Guile正在使用类似的东西,等等),特别是在Linux上(这是我唯一关心的操作系统;如果这很重要,我正在使用debian/sid/x86-64,libgc-devpackage is version1:7.4.2-8所以boehm gc是7.4.2)。
然而,Boehm的GC要求了解使用它的每个线程。它的头文件将重新定义为

# define pthread_create GC_pthread_create

实际上,Boehm的GC需要在新线程调用堆栈的早期调用gc_pthreads_redirects.h
在过去,glib(2.46)提供了一种使用GC_register_my_thread重新定义内存分配的方法,并且不能再使用(my debian的pthread_create包的版本为GC_pthread_create)。这里有一个struct GMemVTable which is deprecated但是当查看glib源代码时,在释放它们之前只需清除内存区域。
最近的gtk3(mylibglib2.02.0-devpackage的版本为2.50.3-2)正在使用(间接地)g_mem_gc_friendlythrulibgtk-3-dev global boolean创建线程(可能与dbus相关,也可能与gtktextview有关)。而且没有办法(除了修补源代码)得到创建线程的通知。恐怕安装的任何GTK回调(例如,使用Glib thread functions)都可以从这些线程调用。或者,如果我用一些可能使用(或访问)某些缓冲区的方法将GTK小部件子类化,那么可能会发生灾难。
另一方面,在GTK中有一个很强的编码规则,所有的GTK操作都应该只在主线程中发生。引用页面:
然而,GTK+不是线程安全的。您应该只使用来自线程3.22.11-1pthread_create的gtk+和gdk。这通常被称为“主线程”。
如果我自己遵循这条规则,我确信没有任何内部GTK代码会从某个非主线程调用我的回调(使用boehm gc)?
我的直觉是,如果GTK内部(而不是直接由我的代码)从主线程外部调用g_signal_connect,就会发生灾难。
(因为这些GTK内部线程尚未使用GC_malloc启动;可能会调用某些代码,例如,因为我正在对某个现有的GTK小部件进行子类化,或者因为我连接了一些GTK信号,即使我自己没有在主线程之外使用GTK&Boehm GC编写代码)。
重点是Boehm的GC需要扫描可能使用它的每个线程中的每个堆栈。
fwiw,我报告了一个可能的gtk_init()关于gtk Bugzilla。
一个典型的例子是来自GTK-3.22.11 tarball的gtk_main()GC_allocGdk3 Threads非常间接地通过GC_pthread_create通过gtk+-3.22.11/examples/application9/

最佳答案

写GTK+时没有考虑垃圾收集器。您必须修改gdk和它所建立的库,才能调用gc_*分配函数来工作。在这里,仅仅通知GC额外的glib线程似乎不是一个解决方案。
也就是说,如果gtk+及其使用的库得到了与boehm gc不同的堆的支持,这可能是没有问题的。您的应用程序可能并不完全没有内存泄漏和其他问题,但至少您编写的所有代码都是正确的gc'd。

关于c - 最近的GTK 3.22仍然是Boehm GC友好(线程问题)?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/43141659/

10-12 00:12
查看更多