Ist das aktuelle GTK 3.22 immer noch Boehm GC-freundlich (Thread-Problem)?

Lesezeit: 5 Minuten

Benutzeravatar von Basile Starynkevitch
Basile Starynkevitch

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() und gtk_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

Gtk ruft keinen Signalhandler von einem Nicht-Haupt-Thread auf. Jeder Arbeitsthread, den Sie in einer Gtk-Anwendung finden, interagiert mit dem Hauptthread über eine Nachrichtenwarteschlange. Sie können das in der Glib-Quelle sehen. Siehe zum Beispiel die Implementierung von g_dbus_connection_signal_subscribe() und schedule_callbacks() in gdbusconnection.c.(Ein Worker-Thread ruft auf g_source_attach(…, Abonnent->Kontext)wobei das zweite Argument was ist g_main_context_ref_thread_default() ist zurückgekommen.)

Sie müssen also keine Speicherzuweisungsroutinen mit überschreiben g_mem_set_vtable(). Wenn Sie das zuvor getan haben, war das ein sehr schlechtes Design, bei dem Sie die perfekte manuelle Speicherverwaltungsimplementierung in GLib/Gtk durch ein automatisches, aber unvollkommenes (und nicht stabiles) Speicherverwaltungsschema, Boehm GC, ersetzt haben.

1415100cookie-checkIst das aktuelle GTK 3.22 immer noch Boehm GC-freundlich (Thread-Problem)?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy