Das Böhms konservativer Garbage Collector ganz praktisch (zB Bigloo nutzt es, List verwendet etwas Ähnliches usw.), insbesondere unter Linux (das ist das einzige Betriebssystem, das mir wichtig ist; ich verwende Debian/Sid/x86-64, falls das wichtig ist, und libgc-dev
Paket ist Version 1:7.4.2-8
also ist der Boehm GC 7.4.2).
Jedoch, Böhms GC erfordert, jeden Thread zu kennen, der es verwendet. Es ist gc_pthreads_redirects.h (mehr oder weniger interne) Header-Datei definiert sich neu pthread_create
wie
# define pthread_create GC_pthread_create
Was Boehm’s GC braucht, ist eigentlich GC_register_my_thread früh in der neuen Thread-Aufrufliste aufgerufen werden (und GC_pthread_create
macht das).
In der Vergangenheit bot Glib (2.46) eine Möglichkeit, die Speicherzuweisung mit neu zu definieren struct GMemVTable
welches ist veraltet und kann nicht verwendet werden mehr (mein Debian’s libglib2.02.0-dev
Paket ist Version 2.50.3-2
). Da ist ein g_mem_gc_friendly
globaler boolescher Wert aber wenn man in den Glib-Quellcode schaut, löscht es einfach Speicherzonen, bevor es sie freigibt.
Aktuelles GTK3 (my libgtk-3-dev
Paket hat Version 3.22.11-1
) erstellen Threads (für etwas, das wahrscheinlich mit Dbus und vielleicht auch mit GtkTextView zu tun hat …) und verwenden (indirekt) pthread_create
durch Glib-Thread-Funktionen. Und es gibt keine Möglichkeit (außer durch Patchen des Quellcodes), über diese Thread-Erstellung benachrichtigt zu werden. Ich fürchte, als jeder GTK-Callback, den ich installieren würde (z. B. mit g_signal_connect
) können von diesen Threads aufgerufen werden. Oder wenn ich ein GTK-Widget mit einigen Methoden unterteile, die einige verwenden (oder darauf zugreifen) könnten GC_malloc
-ed-Puffer könnte es zu einer Katastrophe kommen.
Andererseits gibt es in GTK eine strenge Codierungsregel, dass alle GTK-Operationen nur im Haupt-Thread stattfinden sollten. Zitieren Gdk3-Threads Seite:
GTK+jedoch, ist nicht Thread sicher. Sie sollten nur GTK+ und GDK aus dem Thread verwenden
gtk_init()
undgtk_main()
aufgerufen wurden. Dies wird normalerweise als „Hauptthread“ bezeichnet.
Wenn ich diese Regel selbst befolge, bin ich mir sicher, dass kein interner GTK-Code jemals meine Rückrufe (mit Boehm GC) von einem Nicht-Haupt-Thread aufrufen wird?
Meine Intuition ist das, wenn überhaupt GC_alloc
von außerhalb des Haupt-Threads durch GTK-Interna (nicht direkt durch meinen Code) aufgerufen wird, würde ein Desaster passieren (weil diese GTK-internen Threads nicht gestartet wurden GC_pthread_create
; dort könnte ein Teil meines Codes aufgerufen werden, z. B. weil ich ein vorhandenes GTK-Widget unterklassifiziere oder weil ich ein GTK-Signal verbunden habe, selbst wenn ich selbst nicht mit GTK & Boehm GC außerhalb des Haupt-Threads codiere.).
Der Punkt ist, dass Boehms GC jeden Stack in jedem Thread scannen muss, der ihn möglicherweise verwendet.
FWIW, ich habe eine mögliche gemeldet Fehler#780815 auf GTK-Bugzilla.
Ein typisches Beispiel ist gtk+-3.22.11/examples/application9/
aus GTK-3.22.11-Tarball. pthread_create
wird genannt sehr indirekt durch g_application_run
über g_bus_get_sync
Da GTK+ im Allgemeinen nicht Thread-sicher ist (d. h. die GTK+-Funktionen sind nicht Thread-sicher und gehen davon aus, dass auf die Objekte, auf die sie verweisen, und auf die sie zugreifen, nur in einem einzigen Thread zugegriffen wird), kann ich nur erkennen, dass GTK+-Callbacks sicher sein können , wenn sie im “Hauptthread” ausgeführt werden. Sind Sie anderer Meinung?
– Nominelles Tier
1. April 2017 um 8:48 Uhr
Wie genau (könnten sie in einem anderen Thread mutex-gesperrt ausgeführt werden)? Da die GTK+-Funktionen nicht Thread-sicher sind und es keine Einschränkungen gibt, auf welche Objekte ein GTK+-Signal-Handler zugreifen kann (AFAIK), muss der Thread, der den GTK+-Signal-Handler ausführt, der „Haupt-Thread“ sein; Andernfalls ist ein solcher Handler darauf beschränkt, nur auf die durch Mutex geschützten Objekte zuzugreifen. Ich habe solche Einschränkungen nicht dokumentiert gesehen. Also, auf welcher Grundlage müssen Sie davon ausgehen “könnte mutex-gesperrt ausgeführt werden”? (Der Objektzugriff ist schließlich nicht auf GTK+-Funktionen beschränkt; ein globaler GTK+-Mutex würde nur vor dem Zugriff auf GTK+-Funktionen schützen?)
– Nominelles Tier
1. April 2017 um 15:04 Uhr
Ich habe die Einzelheiten vergessen. Aber ich habe gdb vor ein paar Jahren auf GtkTextView-Code ausgeführt und war von mehreren Threads überrascht.
– Basile Starynkevitch
1. April 2017 um 15:05 Uhr
Meine Frage war sowieso sinnlos: Es gibt keinen Grund anzunehmen, dass die zusätzlichen Threads nichts mit der Speicherverwaltung zu tun haben. Tatsächlich ist das wahrscheinlich genau das, was sie tun sollen: asynchrone Übertragung von Daten zu/von GTK+-Strukturen. Das bedeutet, dass Sie diese zusätzlichen Threads über erstellen müssen
GC_pthread_create()
ohnehin. Unglückliche Situation.– Nominelles Tier
1. April 2017 um 16:03 Uhr
…nun, ich verstehe, dass das, was folgt, ein ziemlich hässlicher Hack ist, aber: warum nicht einfach Haken Sie die erforderlichen Funktionen ein und sie durch richtige Trampoline ersetzen, die rufen, was Böhm braucht? Die Erstellung von Threads ist sowieso teuer, daher bezweifle ich, dass dies die Leistung beeinträchtigt.
– versteckevorkgb
20. Juli 2017 um 16:24 Uhr