Подтвердить что ты не робот

Недавнее GTK 3.22 по-прежнему совместимо с Boehm GC (проблема с потоком)?

консервативный сборщик мусора 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

4b9b3361

Ответ 1

GTK + не написан с учетом сборщика мусора. Вам нужно будет изменить GDK и библиотеки, на которых он построен, чтобы вызвать функции распределения GC_ * для этого. Простое уведомление GC дополнительных потоков GLib, похоже, не является решением.

Тем не менее, это может быть не проблема, если GTK + и библиотеки, которые он использует, поддерживаются другой кучей, чем GC Boehm. Ваше приложение может быть не полностью очищено от утечек памяти и других проблем, но, по крайней мере, весь написанный вами код будет соответствующим образом GC'd.