консервативный сборщик мусора Boehm весьма полезен (например, Bigloo использует его, Guile использует что-то подобное и т.д.), особенно в Linux (что является единственным OS, о которой я забочусь, я использую Debian/Sid/x86-64, если это имеет значение, а libgc-dev
- версия 1:7.4.2-8
, поэтому GC Boehm - это 7.4.2).
Однако Boehm GC требует знать каждый поток, используя его. Его gc_pthreads_redirects.h (более или менее внутренний) заголовочный файл переопределяет pthread_create
как
# define pthread_create GC_pthread_create
Собственно, то, что требуется GC Boehm, GC_register_my_thread, будет вызвано в начале нового стека вызовов потока (и GC_pthread_create
делает это).
В прошлом Glib (2.46) предоставил возможность переопределить распределение памяти с помощью struct GMemVTable
, который устарел и больше не может использоваться (мой пакет Debian libglib2.02.0-dev
- версия 2.50.3-2
). Существует g_mem_gc_friendly
global boolean, но при изучении исходного кода Glib он просто очищает зоны памяти, прежде чем освобождать их.
Недавний GTK3 (мой пакет libgtk-3-dev
имеет версию 3.22.11-1
) создает потоки (для чего-то, вероятно, связанного с Dbus, а возможно и с GtkTextView...), используя (косвенно) pthread_create
thru Функции glib thread. И нет способа (за исключением исправления исходного кода), чтобы получать уведомление об этом создании потока. Я боюсь, что любой обратный вызов GTK, который я установил (например, используя g_signal_connect
), можно было бы вызывать из этих потоков. Или, если я подклассифицирую виджет GTK с помощью некоторых методов, которые могут использовать (или получить) некоторый буфер GC_malloc
-ed, может произойти катастрофа.
С другой стороны, в GTK существует сильное правило кодирования, что все операции GTK должны выполняться только в основном потоке. Чтобы процитировать страницу Gdk3 Threads:
GTK +, однако не является потокобезопасным. Вы должны использовать только GTK + и GDK из потока
gtk_init()
иgtk_main()
. Обычно это называется "основной поток".
Если я сам следую этому правилу, я уверен, что никакой внутренний код GTK никогда не вызовет мои обратные вызовы (используя Boehm GC) из некоторого не основного потока?
Моя интуиция заключается в том, что если GC_alloc
вызывается извне основного потока с помощью встроенных GTK (не напрямую по моему коду), произойдет катастрофа
(потому что эти внутренние потоки GTK не были запущены с помощью GC_pthread_create
, может быть вызван некоторый из моего кода, например, потому что я подклассифицирую какой-то существующий виджет GTK или потому, что я подключил некоторый сигнал GTK, даже если я сам не код вещи, использующие GTK и Boehm GC вне основного потока.).
Дело в том, что GC Boehm необходимо сканировать каждый стек в каждом потоке, возможно, используя его.
FWIW, я сообщил о возможной ошибке # 780815 в GTK bugzilla.
Типичным примером является gtk+-3.22.11/examples/application9/
из tar файла GTK-3.22.11. pthread_create
называется очень косвенно g_application_run
через g_bus_get_sync