Ich verstehe nicht, warum eine andere Ebene der Indirektion erforderlich ist, wenn die GVL in Ruby C API freigegeben oder erworben wird.
Sowohl rb_thread_call_without_gvl()
als auch rb_thread_call_with_gvl()
erfordern eine Funktion, die nur ein Argument akzeptiert, was nicht immer der Fall ist. Ich möchte meine Argumente in einer Struktur nicht nur für den Zweck der Freigabe der GVL umschließen. Es erschwert die Lesbarkeit des Codes und erfordert das Umwandeln und das Leeren von Zeigern.
Nachdem ich in Ruby Threading-Code untersucht habe, fand ich die GVL_UNLOCK_BEGIN
/GVL_UNLOCK_END
Makros, die Pythons Py_BEGIN_ALLOW_THREADS
/Py_END_ALLOW_THREADS
entspricht, aber ich kann keine Dokumentation über sie finden und wenn sie sicher zu verwenden sind.
Es gibt auch die Makro wird innerhalb rb_thread_call_without_gvl()
verwendet, aber ich bin mir nicht sicher, ob es sicher ist, es als eigenständiges Gerät ohne Aufruf rb_thread_call_without_gvl()
selbst zu verwenden.Freigeben der globalen VM-Sperre in einer C-Erweiterung, ohne eine andere Funktion zu verwenden
Was ist der korrekte Weg zu sicher Freigabe der GVL in der Mitte des Ausführungsablaufs, ohne eine andere Funktion aufrufen zu müssen?
Die API ist so konzipiert, dass Ihr C-Code explizit seine Absicht erklären muss, entweder mit oder ohne GVL zu laufen, so dass er im letzteren Fall die GVL vor der Rückkehr zu Ruby wiederfinden kann. Dies erfordert eine Funktion, die das Freigeben der GVL, das Ausführen des Codes und das Wiedererlangen der GVL einbezieht. Sie müssen Ihren Code in eine Funktion packen, um der Startfunktion mitzuteilen, was zu tun ist. Daher muss die API eine oder eine kleine Anzahl unterstützter Signaturen für die Benutzerfunktion auswählen, da jede Signatur eine separate Startfunktion benötigt. –