Initialisierung, Finalisierung und Threads

Siehe Python-Initialisierungskonfiguration für Details zur Konfiguration des Interpreters vor der Initialisierung.

Vor der Python-Initialisierung

In einer Anwendung, die Python einbettet, muss die Funktion Py_Initialize() aufgerufen werden, bevor andere Python/C-API-Funktionen verwendet werden; mit Ausnahme einiger weniger Funktionen und der globalen Konfigurationsvariablen.

Die folgenden Funktionen können sicher aufgerufen werden, bevor Python initialisiert wurde

Hinweis

Trotz ihrer offensichtlichen Ähnlichkeit mit einigen der oben genannten Funktionen sollten die folgenden Funktionen nicht aufgerufen werden, bevor der Interpreter initialisiert wurde: Py_EncodeLocale(), Py_GetPath(), Py_GetPrefix(), Py_GetExecPrefix(), Py_GetProgramFullPath(), Py_GetPythonHome(), Py_GetProgramName(), PyEval_InitThreads() und Py_RunMain().

Globale Konfigurationsvariablen

Python hat Variablen für die globale Konfiguration, um verschiedene Funktionen und Optionen zu steuern. Standardmäßig werden diese Flags durch Befehlszeilenoptionen gesteuert.

Wenn ein Flag durch eine Option gesetzt wird, ist der Wert des Flags die Anzahl der Male, die die Option gesetzt wurde. Zum Beispiel setzt -b Py_BytesWarningFlag auf 1 und -bb setzt Py_BytesWarningFlag auf 2.

int Py_BytesWarningFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.bytes_warning gesetzt werden, siehe Python-Initialisierungskonfiguration.

Gibt eine Warnung aus, wenn bytes oder bytearray mit str oder bytes mit int verglichen wird. Gibt einen Fehler aus, wenn er größer oder gleich 2 ist.

Gesetzt durch die Option -b.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_DebugFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.parser_debug gesetzt werden, siehe Python-Initialisierungskonfiguration.

Schaltet die Debug-Ausgabe des Parsers ein (nur für Experten, abhängig von den Kompilierungsoptionen).

Gesetzt durch die Option -d und die Umgebungsvariable PYTHONDEBUG.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_DontWriteBytecodeFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.write_bytecode gesetzt werden, siehe Python-Initialisierungskonfiguration.

Wenn auf einen Wert ungleich Null gesetzt, versucht Python nicht, .pyc-Dateien beim Import von Quellmodulen zu schreiben.

Gesetzt durch die Option -B und die Umgebungsvariable PYTHONDONTWRITEBYTECODE.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_FrozenFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.pathconfig_warnings gesetzt werden, siehe Python-Initialisierungskonfiguration.

Unterdrückt Fehlermeldungen bei der Berechnung des Modul-Suchpfads in Py_GetPath().

Privates Flag, das von den Programmen _freeze_module und frozenmain verwendet wird.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_HashRandomizationFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollten PyConfig.hash_seed und PyConfig.use_hash_seed gesetzt werden, siehe Python-Initialisierungskonfiguration.

Auf 1 gesetzt, wenn die Umgebungsvariable PYTHONHASHSEED auf eine nicht-leere Zeichenkette gesetzt ist.

Wenn das Flag nicht Null ist, liest es die Umgebungsvariable PYTHONHASHSEED, um den geheimen Hash-Seed zu initialisieren.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_IgnoreEnvironmentFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.use_environment gesetzt werden, siehe Python-Initialisierungskonfiguration.

Ignoriert alle PYTHON*-Umgebungsvariablen, z. B. PYTHONPATH und PYTHONHOME, die gesetzt sein könnten.

Gesetzt durch die Optionen -E und -I.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_InspectFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.inspect gesetzt werden, siehe Python-Initialisierungskonfiguration.

Wenn ein Skript als erstes Argument übergeben wird oder die Option -c verwendet wird, wird nach der Ausführung des Skripts oder des Befehls der interaktive Modus gestartet, auch wenn sys.stdin nicht wie ein Terminal aussieht.

Gesetzt durch die Option -i und die Umgebungsvariable PYTHONINSPECT.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_InteractiveFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.interactive gesetzt werden, siehe Python-Initialisierungskonfiguration.

Gesetzt durch die Option -i.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_IsolatedFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.isolated gesetzt werden, siehe Python-Initialisierungskonfiguration.

Führt Python im isolierten Modus aus. Im isolierten Modus enthält sys.path weder das Verzeichnis des Skripts noch das Verzeichnis des Benutzers site-packages.

Gesetzt durch die Optionen -I.

Hinzugefügt in Version 3.4.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_LegacyWindowsFSEncodingFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyPreConfig.legacy_windows_fs_encoding gesetzt werden, siehe Python-Initialisierungskonfiguration.

Wenn das Flag nicht Null ist, wird die Kodierung mbcs mit dem Fehlerbehandler replace anstelle der UTF-8-Kodierung mit dem Fehlerbehandler surrogatepass für die Dateisystemkodierung und Fehlerbehandler verwendet.

Auf 1 gesetzt, wenn die Umgebungsvariable PYTHONLEGACYWINDOWSFSENCODING auf eine nicht-leere Zeichenkette gesetzt ist.

Siehe PEP 529 für weitere Details.

Verfügbarkeit: Windows.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_LegacyWindowsStdioFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.legacy_windows_stdio gesetzt werden, siehe Python-Initialisierungskonfiguration.

Wenn das Flag nicht Null ist, wird io.FileIO anstelle von io._WindowsConsoleIO für sys-Standardströmen verwendet.

Auf 1 gesetzt, wenn die Umgebungsvariable PYTHONLEGACYWINDOWSSTDIO auf eine nicht-leere Zeichenkette gesetzt ist.

Siehe PEP 528 für weitere Details.

Verfügbarkeit: Windows.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_NoSiteFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.site_import gesetzt werden, siehe Python-Initialisierungskonfiguration.

Deaktiviert den Import des Moduls site und die damit verbundenen standortspezifischen Manipulationen von sys.path. Deaktiviert diese Manipulationen auch, wenn site später explizit importiert wird (rufen Sie site.main() auf, wenn Sie möchten, dass sie ausgelöst werden).

Gesetzt durch die Option -S.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_NoUserSiteDirectory

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.user_site_directory gesetzt werden, siehe Python-Initialisierungskonfiguration.

Fügt das Verzeichnis Benutzer-site-packages nicht zu sys.path hinzu.

Gesetzt durch die Optionen -s und -I sowie die Umgebungsvariable PYTHONNOUSERSITE.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_OptimizeFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.optimization_level gesetzt werden, siehe Python-Initialisierungskonfiguration.

Gesetzt durch die Option -O und die Umgebungsvariable PYTHONOPTIMIZE.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_QuietFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.quiet gesetzt werden, siehe Python-Initialisierungskonfiguration.

Unterdrückt die Anzeige der Copyright- und Versionsmeldungen, auch im interaktiven Modus.

Gesetzt durch die Option -q.

Hinzugefügt in Version 3.2.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_UnbufferedStdioFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.buffered_stdio gesetzt werden, siehe Python-Initialisierungskonfiguration.

Erzwingt, dass die stdout- und stderr-Streams unbuffered sind.

Gesetzt durch die Option -u und die Umgebungsvariable PYTHONUNBUFFERED.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

int Py_VerboseFlag

Diese API wird aus Kompatibilitätsgründen beibehalten: stattdessen sollte PyConfig.verbose gesetzt werden, siehe Python-Initialisierungskonfiguration.

Gibt eine Meldung aus, jedes Mal wenn ein Modul initialisiert wird, und zeigt den Ort (Dateiname oder eingebautes Modul) an, von dem es geladen wird. Wenn größer oder gleich 2, gibt eine Meldung für jede Datei aus, die bei der Suche nach einem Modul überprüft wird. Bietet auch Informationen zur Modulbereinigung beim Beenden.

Gesetzt durch die Option -v und die Umgebungsvariable PYTHONVERBOSE.

Veraltet seit Version 3.12, wird in Version 3.15 entfernt.

Initialisierung und Finalisierung des Interpreters

void Py_Initialize()
Teil der Stable ABI.

Initialisiert den Python-Interpreter. In einer Anwendung, die Python einbettet, sollte dies aufgerufen werden, bevor andere Python/C-API-Funktionen verwendet werden; siehe Vor der Python-Initialisierung für die wenigen Ausnahmen.

Dies initialisiert die Tabelle der geladenen Module (sys.modules) und erstellt die grundlegenden Module builtins, __main__ und sys. Es initialisiert auch den Modul-Suchpfad (sys.path). Es setzt sys.argv nicht; verwenden Sie die API Python-Initialisierungskonfiguration dafür. Dies ist eine No-Operation, wenn es zum zweiten Mal aufgerufen wird (ohne zuvor Py_FinalizeEx() aufzurufen). Es gibt keinen Rückgabewert; es ist ein fataler Fehler, wenn die Initialisierung fehlschlägt.

Verwenden Sie Py_InitializeFromConfig(), um die Python-Initialisierungskonfiguration anzupassen.

Hinweis

Unter Windows ändert sich der Konsolenmodus von O_TEXT zu O_BINARY, was sich auch auf andere Nutzungen der Konsole mit der C-Laufzeit auswirkt.

void Py_InitializeEx(int initsigs)
Teil der Stable ABI.

Diese Funktion funktioniert wie Py_Initialize(), wenn initsigs 1 ist. Wenn initsigs 0 ist, überspringt sie die Registrierung von Signalhandlern, was nützlich sein kann, wenn CPython als Teil einer größeren Anwendung eingebettet wird.

Verwenden Sie Py_InitializeFromConfig(), um die Python-Initialisierungskonfiguration anzupassen.

PyStatus Py_InitializeFromConfig(const PyConfig *config)

Initialisiert Python aus der Konfiguration config, wie in Initialisierung mit PyConfig beschrieben.

Siehe den Abschnitt Python-Initialisierungskonfiguration für Details zur Vorinitialisierung des Interpreters, zum Befüllen der Laufzeitkonfigurationsstruktur und zum Abfragen der zurückgegebenen Statusstruktur.

int Py_IsInitialized()
Teil der Stable ABI.

Gibt wahr (ungleich Null) zurück, wenn der Python-Interpreter initialisiert wurde, falsch (Null) sonst. Nach dem Aufruf von Py_FinalizeEx() gibt diese Funktion falsch zurück, bis Py_Initialize() erneut aufgerufen wird.

int Py_IsFinalizing()
Teil des Stable ABI seit Version 3.13.

Gibt wahr (ungleich Null) zurück, wenn der Haupt-Python-Interpreter heruntergefahren wird. Gibt andernfalls falsch (Null) zurück.

Hinzugefügt in Version 3.13.

int Py_FinalizeEx()
Teil der Stable ABI seit Version 3.6.

Macht alle von Py_Initialize() vorgenommenen Initialisierungen und die nachfolgende Verwendung von Python/C API-Funktionen rückgängig und zerstört alle seit dem letzten Aufruf von Py_Initialize() erstellten und noch nicht zerstörten Unterinterpreters (siehe Py_NewInterpreter() unten). Dies ist ein No-Op, wenn es zum zweiten Mal aufgerufen wird (ohne vorher Py_Initialize() erneut aufzurufen).

Da dies das Gegenteil von Py_Initialize() ist, sollte es im selben Thread mit demselben aktiven Interpreter aufgerufen werden. Das bedeutet den Hauptthread und den Hauptinterpreter. Dies sollte niemals aufgerufen werden, während Py_RunMain() läuft.

Normalerweise ist der Rückgabewert 0. Bei Fehlern während der Finalisierung (Leeren gepufferter Daten) wird -1 zurückgegeben.

Beachten Sie, dass Python nach besten Kräften versucht, allen vom Python-Interpreter zugewiesenen Speicher freizugeben. Daher sollte jede C-Erweiterung sicherstellen, dass alle zuvor zugewiesenen PyObjects ordnungsgemäß bereinigt werden, bevor sie in nachfolgenden Aufrufen von Py_Initialize() verwendet werden. Andernfalls könnte dies zu Sicherheitslücken und fehlerhaftem Verhalten führen.

Diese Funktion wird aus verschiedenen Gründen bereitgestellt. Eine einbettende Anwendung möchte möglicherweise Python neu starten, ohne die Anwendung selbst neu starten zu müssen. Eine Anwendung, die den Python-Interpreter aus einer dynamisch ladbaren Bibliothek (oder DLL) geladen hat, möchte möglicherweise allen von Python zugewiesenen Speicher freigeben, bevor sie die DLL entlädt. Bei der Jagd nach Speicherlecks in einer Anwendung möchte ein Entwickler möglicherweise allen von Python zugewiesenen Speicher freigeben, bevor er die Anwendung beendet.

Fehler und Vorbehalte: Die Zerstörung von Modulen und Objekten in Modulen erfolgt in zufälliger Reihenfolge; dies kann dazu führen, dass Destruktoren (__del__() Methoden) fehlschlagen, wenn sie von anderen Objekten (sogar Funktionen) oder Modulen abhängen. Von Python dynamisch geladene Erweiterungsmodule werden nicht entladen. Geringe Mengen an vom Python-Interpreter zugewiesenen Speicher werden möglicherweise nicht freigegeben (wenn Sie ein Leck finden, melden Sie es bitte). Speicher, der in zirkulären Referenzen zwischen Objekten gebunden ist, wird nicht freigegeben. Internierte Zeichenketten werden alle unabhängig von ihrer Referenzanzahl freigegeben. Einige von Erweiterungsmodulen zugewiesene Speicher werden möglicherweise nicht freigegeben. Einige Erweiterungen funktionieren möglicherweise nicht richtig, wenn ihre Initialisierungsroutine mehr als einmal aufgerufen wird; dies kann passieren, wenn eine Anwendung Py_Initialize() und Py_FinalizeEx() mehr als einmal aufruft. Py_FinalizeEx() darf nicht rekursiv aus sich selbst heraus aufgerufen werden. Daher darf es nicht von Code aufgerufen werden, der als Teil des Interpreter-Abschlussprozesses ausgeführt werden kann, wie z. B. atexit-Handler, Objektfinalisierer oder beliebiger Code, der beim Leeren der stdout- und stderr-Dateien ausgeführt werden kann.

Löst ein Auditing-Ereignis cpython._PySys_ClearAuditHooks ohne Argumente aus.

Hinzugefügt in Version 3.6.

void Py_Finalize()
Teil der Stable ABI.

Dies ist eine abwärtskompatible Version von Py_FinalizeEx(), die den Rückgabewert ignoriert.

int Py_BytesMain(int argc, char **argv)
Teil der Stable ABI seit Version 3.8.

Ähnlich wie Py_Main(), aber argv ist ein Array von Byte-Strings, wodurch die aufrufende Anwendung den Textdekodierungsschritt an die CPython-Laufzeit delegieren kann.

Hinzugefügt in Version 3.8.

int Py_Main(int argc, wchar_t **argv)
Teil der Stable ABI.

Das Hauptprogramm für den Standardinterpreter, das einen vollständigen Initialisierungs-/Finalisierungszyklus sowie zusätzliches Verhalten zur Implementierung des Lesens von Konfigurationseinstellungen aus der Umgebung und der Befehlszeile und zur anschließenden Ausführung von __main__ gemäß Befehlszeile kapselt.

Dies steht für Programme zur Verfügung, die die vollständige CPython-Befehlszeilenschnittstelle unterstützen möchten und nicht nur eine Python-Laufzeit in eine größere Anwendung einbetten.

Die Parameter argc und argv ähneln denen, die an die main() Funktion eines C-Programms übergeben werden, mit dem Unterschied, dass die argv-Einträge zuerst mit Py_DecodeLocale() in wchar_t konvertiert werden. Es ist auch wichtig zu beachten, dass die Einträge der Argumentliste geändert werden können, um auf andere Zeichenketten zu zeigen als die, die übergeben wurden (die Inhalte der von der Argumentliste gezeigten Zeichenketten werden jedoch nicht geändert).

Der Rückgabewert ist 2, wenn die Argumentliste keine gültige Python-Befehlszeile darstellt, und andernfalls derselbe wie bei Py_RunMain().

In Bezug auf die in der Sektion Laufzeitkonfiguration dokumentierten CPython-Laufzeitkonfigurations-APIs (und ohne Berücksichtigung der Fehlerbehandlung) ist Py_Main ungefähr äquivalent zu

PyConfig config;
PyConfig_InitPythonConfig(&config);
PyConfig_SetArgv(&config, argc, argv);
Py_InitializeFromConfig(&config);
PyConfig_Clear(&config);

Py_RunMain();

Im normalen Gebrauch ruft eine einbettende Anwendung diese Funktion *anstelle* des direkten Aufrufs von Py_Initialize(), Py_InitializeEx() oder Py_InitializeFromConfig() auf, und alle Einstellungen werden wie anderswo in dieser Dokumentation beschrieben angewendet. Wenn diese Funktion stattdessen *nach* einem vorherigen Laufzeitinitialisierungs-API-Aufruf aufgerufen wird, hängt genau davon ab, welche Umgebungs- und Befehlszeilenkonfigurationseinstellungen aktualisiert werden, versionabhängig (da es davon abhängt, welche Einstellungen unterstützt werden, wenn sie bereits einmal gesetzt wurden, als die Laufzeit zum ersten Mal initialisiert wurde).

int Py_RunMain(void)

Führt das Hauptmodul in einer vollständig konfigurierten CPython-Laufzeitumgebung aus.

Führt den Befehl (PyConfig.run_command), das Skript (PyConfig.run_filename) oder das Modul (PyConfig.run_module) aus, die auf der Befehlszeile oder in der Konfiguration angegeben sind. Wenn keiner dieser Werte gesetzt ist, wird die interaktive Python-Eingabeaufforderung (REPL) unter Verwendung des globalen Namensraums des Moduls __main__ gestartet.

Wenn PyConfig.inspect nicht gesetzt ist (Standard), ist der Rückgabewert 0, wenn der Interpreter normal beendet wird (d.h. ohne eine Ausnahme auszulösen), der Exit-Status eines unbehandelten SystemExit oder 1 für jede andere unbehandelte Ausnahme.

Wenn PyConfig.inspect gesetzt ist (z. B. wenn die Option -i verwendet wird), wird anstatt der Rückgabe beim Beenden des Interpreters die Ausführung in einer interaktiven Python-Eingabeaufforderung (REPL) unter Verwendung des globalen Namensraums des Moduls __main__ fortgesetzt. Wenn der Interpreter mit einer Ausnahme beendet wurde, wird diese sofort in der REPL-Sitzung ausgelöst. Der Rückgabewert der Funktion wird dann durch die Art und Weise bestimmt, wie die *REPL-Sitzung* endet: 0, 1 oder der Status eines SystemExit, wie oben angegeben.

Diese Funktion finalisiert immer den Python-Interpreter, bevor sie zurückkehrt.

Siehe Python-Konfiguration für ein Beispiel einer angepassten Python-Konfiguration, die immer im isolierten Modus unter Verwendung von Py_RunMain() ausgeführt wird.

int PyUnstable_AtExit(PyInterpreterState *interp, void (*func)(void*), void *data)
Dies ist eine Instabile API. Sie kann sich ohne Vorwarnung in kleineren Releases ändern.

Registriert einen atexit-Callback für den Zielinterpreter interp. Dies ist ähnlich wie Py_AtExit(), nimmt aber einen expliziten Interpreter und einen Datenzeiger für den Callback entgegen.

Es muss ein angehängter Thread-Status für interp vorhanden sein.

Hinzugefügt in Version 3.13.

Prozessweite Parameter

void Py_SetProgramName(const wchar_t *name)
Teil der Stable ABI.

Diese API wird aus Gründen der Abwärtskompatibilität beibehalten: stattdessen sollte PyConfig.program_name gesetzt werden, siehe Python-Initialisierungskonfiguration.

Diese Funktion sollte vor dem ersten Aufruf von Py_Initialize() aufgerufen werden, falls sie überhaupt aufgerufen wird. Sie teilt dem Interpreter den Wert des argv[0]-Arguments der main()-Funktion des Programms mit (konvertiert in Wide-Zeichen). Dies wird von Py_GetPath() und einigen anderen unten stehenden Funktionen verwendet, um die Python-Laufzeitbibliotheken relativ zur Interpreter-Executable zu finden. Der Standardwert ist 'python'. Das Argument sollte auf eine null-terminierte Wide-Zeichenkette im statischen Speicher verweisen, deren Inhalt sich während der Laufzeit des Programms nicht ändert. Kein Code im Python-Interpreter wird den Inhalt dieses Speichers ändern.

Verwenden Sie Py_DecodeLocale(), um eine Byte-Zeichenkette in eine wchar_t* Zeichenkette zu dekodieren.

Veraltet seit Version 3.11, wird in Version 3.15 entfernt.

wchar_t *Py_GetProgramName()
Teil der Stable ABI.

Gibt den mit PyConfig.program_name gesetzten Programmnamen oder den Standardwert zurück. Die zurückgegebene Zeichenkette verweist auf statischen Speicher; der Aufrufer sollte ihren Wert nicht ändern.

Diese Funktion sollte nicht vor Py_Initialize() aufgerufen werden, andernfalls gibt sie NULL zurück.

Geändert in Version 3.10: Gibt jetzt NULL zurück, wenn sie vor Py_Initialize() aufgerufen wird.

Veraltet seit Version 3.13, wird in Version 3.15 entfernt: Verwenden Sie stattdessen PyConfig_Get("executable") (sys.executable).

wchar_t *Py_GetPrefix()
Teil der Stable ABI.

Gibt das Präfix für installierte plattformunabhängige Dateien zurück. Dies wird anhand einer Reihe komplizierter Regeln aus dem mit PyConfig.program_name gesetzten Programmnamen und einigen Umgebungsvariablen abgeleitet; wenn der Programname beispielsweise '/usr/local/bin/python' ist, ist das Präfix '/usr/local'. Die zurückgegebene Zeichenkette verweist auf statischen Speicher; der Aufrufer sollte ihren Wert nicht ändern. Dies entspricht der prefix-Variable im obersten Makefile und dem --prefix-Argument für das configure-Skript während des Erstellungsprozesses. Der Wert ist für Python-Code als sys.base_prefix verfügbar. Er ist nur unter Unix nützlich. Siehe auch die nächste Funktion.

Diese Funktion sollte nicht vor Py_Initialize() aufgerufen werden, andernfalls gibt sie NULL zurück.

Geändert in Version 3.10: Gibt jetzt NULL zurück, wenn sie vor Py_Initialize() aufgerufen wird.

Veraltet seit Version 3.13, wird in Version 3.15 entfernt: Verwenden Sie stattdessen PyConfig_Get("base_prefix") (sys.base_prefix). Verwenden Sie PyConfig_Get("prefix") (sys.prefix), wenn virtuelle Umgebungen behandelt werden müssen.

wchar_t *Py_GetExecPrefix()
Teil der Stable ABI.

Gibt das exec-prefix für installierte plattformabhängige Dateien zurück. Dies wird anhand einer Reihe komplizierter Regeln aus dem mit PyConfig.program_name gesetzten Programmnamen und einigen Umgebungsvariablen abgeleitet; wenn der Programname beispielsweise '/usr/local/bin/python' ist, ist der exec-prefix '/usr/local'. Die zurückgegebene Zeichenkette verweist auf statischen Speicher; der Aufrufer sollte ihren Wert nicht ändern. Dies entspricht der exec_prefix-Variable im obersten Makefile und dem --exec-prefix-Argument für das configure-Skript während des Erstellungsprozesses. Der Wert ist für Python-Code als sys.base_exec_prefix verfügbar. Er ist nur unter Unix nützlich.

Hintergrund: Der exec-prefix unterscheidet sich vom prefix, wenn plattformabhängige Dateien (wie ausführbare Dateien und gemeinsam genutzte Bibliotheken) in einem anderen Verzeichnisbaum installiert werden. Bei einer typischen Installation können plattformabhängige Dateien im /usr/local/plat-Unterbaum installiert werden, während plattformunabhängige Dateien in /usr/local installiert werden.

Im Allgemeinen ist eine Plattform eine Kombination aus Hardware- und Softwarefamilien, z. B. werden Sparc-Maschinen, die das Solaris 2.x-Betriebssystem ausführen, als dieselbe Plattform betrachtet, aber Intel-Maschinen, die Solaris 2.x ausführen, sind eine andere Plattform, und Intel-Maschinen, die Linux ausführen, sind eine weitere Plattform. Verschiedene Hauptrevisionen desselben Betriebssystems bilden normalerweise auch verschiedene Plattformen. Nicht-Unix-Betriebssysteme sind eine andere Sache; die Installationsstrategien auf diesen Systemen sind so unterschiedlich, dass prefix und exec-prefix bedeutungslos sind und auf eine leere Zeichenkette gesetzt werden. Beachten Sie, dass kompilierte Python-Bytecode-Dateien plattformunabhängig sind (aber nicht unabhängig von der Python-Version, mit der sie kompiliert wurden!).

Systemadministratoren wissen, wie sie die Programme mount oder automount konfigurieren, um /usr/local zwischen Plattformen zu teilen, während /usr/local/plat für jede Plattform ein anderes Dateisystem ist.

Diese Funktion sollte nicht vor Py_Initialize() aufgerufen werden, andernfalls gibt sie NULL zurück.

Geändert in Version 3.10: Gibt jetzt NULL zurück, wenn sie vor Py_Initialize() aufgerufen wird.

Veraltet seit Version 3.13, wird in Version 3.15 entfernt: Verwenden Sie stattdessen PyConfig_Get("base_exec_prefix") (sys.base_exec_prefix). Verwenden Sie PyConfig_Get("exec_prefix") (sys.exec_prefix), wenn virtuelle Umgebungen behandelt werden müssen.

wchar_t *Py_GetProgramFullPath()
Teil der Stable ABI.

Gibt den vollständigen Programmnamen der Python-Executable zurück; dies wird als Nebeneffekt der Ableitung des Standard-Modul-Suchpfads aus dem Programmnamen (gesetzt durch PyConfig.program_name) berechnet. Die zurückgegebene Zeichenkette verweist auf statischen Speicher; der Aufrufer sollte ihren Wert nicht ändern. Der Wert ist für Python-Code als sys.executable verfügbar.

Diese Funktion sollte nicht vor Py_Initialize() aufgerufen werden, andernfalls gibt sie NULL zurück.

Geändert in Version 3.10: Gibt jetzt NULL zurück, wenn sie vor Py_Initialize() aufgerufen wird.

Veraltet seit Version 3.13, wird in Version 3.15 entfernt: Verwenden Sie stattdessen PyConfig_Get("executable") (sys.executable).

wchar_t *Py_GetPath()
Teil der Stable ABI.

Gibt den Standard-Modul-Suchpfad zurück; dieser wird aus dem Programmnamen (gesetzt durch PyConfig.program_name) und einigen Umgebungsvariablen berechnet. Die zurückgegebene Zeichenkette besteht aus einer Reihe von Verzeichnissen, die durch ein plattformabhängiges Trennzeichen getrennt sind. Das Trennzeichen ist ':' unter Unix und macOS, ';' unter Windows. Die zurückgegebene Zeichenkette verweist auf statischen Speicher; der Aufrufer sollte ihren Wert nicht ändern. Die Liste sys.path wird beim Start des Interpreters mit diesem Wert initialisiert; sie kann (und wird normalerweise) später geändert werden, um den Suchpfad für das Laden von Modulen zu ändern.

Diese Funktion sollte nicht vor Py_Initialize() aufgerufen werden, andernfalls gibt sie NULL zurück.

Geändert in Version 3.10: Gibt jetzt NULL zurück, wenn sie vor Py_Initialize() aufgerufen wird.

Veraltet seit Version 3.13, wird in Version 3.15 entfernt: Verwenden Sie stattdessen PyConfig_Get("module_search_paths") (sys.path).

const char *Py_GetVersion()
Teil der Stable ABI.

Gibt die Version dieses Python-Interpreters zurück. Dies ist eine Zeichenkette, die etwa so aussieht:

"3.0a5+ (py3k:63103M, May 12 2008, 00:53:55) \n[GCC 4.2.3]"

Das erste Wort (bis zum ersten Leerzeichen) ist die aktuelle Python-Version; die ersten Zeichen sind die Haupt- und Nebenversion, getrennt durch einen Punkt. Die zurückgegebene Zeichenkette verweist auf statischen Speicher; der Aufrufer sollte ihren Wert nicht ändern. Der Wert ist für Python-Code als sys.version verfügbar.

Siehe auch die Konstante Py_Version.

const char *Py_GetPlatform()
Teil der Stable ABI.

Gibt den Plattform-Identifikator für die aktuelle Plattform zurück. Unter Unix ist dies der "offizielle" Name des Betriebssystems, in Kleinbuchstaben umgewandelt, gefolgt von der Hauptrevisionsnummer; z. B. für Solaris 2.x, das auch als SunOS 5.x bekannt ist, ist der Wert 'sunos5'. Unter macOS ist es 'darwin'. Unter Windows ist es 'win'. Die zurückgegebene Zeichenkette verweist auf statischen Speicher; der Aufrufer sollte ihren Wert nicht ändern. Der Wert ist für Python-Code als sys.platform verfügbar.

const char *Py_GetCopyright()
Teil der Stable ABI.

Gibt die offizielle Copyright-Zeichenkette für die aktuelle Python-Version zurück, zum Beispiel

'Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam'

Die zurückgegebene Zeichenkette verweist auf statischen Speicher; der Aufrufer sollte ihren Wert nicht ändern. Der Wert ist für Python-Code als sys.copyright verfügbar.

const char *Py_GetCompiler()
Teil der Stable ABI.

Gibt eine Angabe des für die Erstellung der aktuellen Python-Version verwendeten Compilers zurück, in eckigen Klammern, zum Beispiel

"[GCC 2.7.2.2]"

Die zurückgegebene Zeichenkette verweist auf statischen Speicher; der Aufrufer sollte ihren Wert nicht ändern. Der Wert ist für Python-Code als Teil der Variablen sys.version verfügbar.

const char *Py_GetBuildInfo()
Teil der Stable ABI.

Gibt Informationen über die Sequenznummer und das Erstellungsdatum und -zeit der aktuellen Python-Interpreter-Instanz zurück, zum Beispiel

"#67, Aug  1 1997, 22:34:28"

Die zurückgegebene Zeichenkette verweist auf statischen Speicher; der Aufrufer sollte ihren Wert nicht ändern. Der Wert ist für Python-Code als Teil der Variablen sys.version verfügbar.

void PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
Teil der Stable ABI.

Diese API wird aus Gründen der Abwärtskompatibilität beibehalten: stattdessen sollte PyConfig.argv, PyConfig.parse_argv und PyConfig.safe_path gesetzt werden, siehe Python-Initialisierungskonfiguration.

Setzt sys.argv basierend auf argc und argv. Diese Parameter ähneln denen, die an die main()-Funktion des Programms übergeben werden, mit dem Unterschied, dass der erste Eintrag sich auf die auszuführende Skriptdatei beziehen sollte und nicht auf die Python-Interpreter-Executable. Wenn kein Skript ausgeführt werden soll, kann der erste Eintrag in argv eine leere Zeichenkette sein. Wenn diese Funktion sys.argv nicht initialisieren kann, wird über Py_FatalError() ein fataler Zustand gemeldet.

Wenn updatepath null ist, tut die Funktion nichts weiter. Wenn updatepath ungleich null ist, modifiziert die Funktion auch sys.path gemäß dem folgenden Algorithmus:

  • Wenn der Name eines vorhandenen Skripts in argv[0] übergeben wird, wird der absolute Pfad des Verzeichnisses, in dem sich das Skript befindet, am Anfang von sys.path eingefügt.

  • Andernfalls (d.h., wenn argc 0 ist oder argv[0] nicht auf einen vorhandenen Dateinamen zeigt), wird eine leere Zeichenkette am Anfang von sys.path eingefügt, was dasselbe ist wie das Einfügen des aktuellen Arbeitsverzeichnisses (".").

Verwenden Sie Py_DecodeLocale(), um eine Byte-Zeichenkette in eine wchar_t* Zeichenkette zu dekodieren.

Siehe auch PyConfig.orig_argv und PyConfig.argv Mitglieder der Python-Initialisierungskonfiguration.

Hinweis

Es wird empfohlen, dass Anwendungen, die den Python-Interpreter für andere Zwecke als die Ausführung eines einzelnen Skripts einbetten, 0 als updatepath übergeben und sys.path selbst aktualisieren, wenn gewünscht. Siehe CVE 2008-5983.

Auf Versionen vor 3.1.3 können Sie den gleichen Effekt erzielen, indem Sie das erste Element von sys.path manuell entfernen, nachdem Sie PySys_SetArgv() aufgerufen haben, zum Beispiel mit

PyRun_SimpleString("import sys; sys.path.pop(0)\n");

Hinzugefügt in Version 3.1.3.

Veraltet seit Version 3.11, wird in Version 3.15 entfernt.

void PySys_SetArgv(int argc, wchar_t **argv)
Teil der Stable ABI.

Diese API wird aus Gründen der Abwärtskompatibilität beibehalten: stattdessen sollte PyConfig.argv und PyConfig.parse_argv gesetzt werden, siehe Python Initialisierungskonfiguration.

Diese Funktion funktioniert wie PySys_SetArgvEx() mit *updatepath* auf 1 gesetzt, es sei denn, der python Interpreter wurde mit -I gestartet.

Verwenden Sie Py_DecodeLocale(), um eine Byte-Zeichenkette in eine wchar_t* Zeichenkette zu dekodieren.

Siehe auch PyConfig.orig_argv und PyConfig.argv Mitglieder der Python-Initialisierungskonfiguration.

Geändert in Version 3.4: Der Wert von *updatepath* hängt von -I ab.

Veraltet seit Version 3.11, wird in Version 3.15 entfernt.

void Py_SetPythonHome(const wchar_t *home)
Teil der Stable ABI.

Diese API wird aus Gründen der Abwärtskompatibilität beibehalten: stattdessen sollte PyConfig.home gesetzt werden, siehe Python Initialisierungskonfiguration.

Setzt das Standardverzeichnis "home", d.h. den Speicherort der Standard-Python-Bibliotheken. Siehe PYTHONHOME für die Bedeutung des Argumentstrings.

Das Argument sollte auf eine nullterminierte Zeichenkette im statischen Speicher zeigen, deren Inhalt sich während der Ausführung des Programms nicht ändert. Kein Code im Python-Interpreter ändert den Inhalt dieses Speichers.

Verwenden Sie Py_DecodeLocale(), um eine Byte-Zeichenkette in eine wchar_t* Zeichenkette zu dekodieren.

Veraltet seit Version 3.11, wird in Version 3.15 entfernt.

wchar_t *Py_GetPythonHome()
Teil der Stable ABI.

Gibt das Standard-"home"-Verzeichnis zurück, d.h. den von PyConfig.home gesetzten Wert, oder den Wert der Umgebungsvariable PYTHONHOME, falls diese gesetzt ist.

Diese Funktion sollte nicht vor Py_Initialize() aufgerufen werden, andernfalls gibt sie NULL zurück.

Geändert in Version 3.10: Gibt jetzt NULL zurück, wenn sie vor Py_Initialize() aufgerufen wird.

Seit Version 3.13 veraltet, wird in Version 3.15 entfernt: Verwenden Sie stattdessen PyConfig_Get("home") oder die Umgebungsvariable PYTHONHOME.

Thread-Status und der Global Interpreter Lock

Sofern es sich nicht um einen free-threaded Build von CPython handelt, ist der Python-Interpreter nicht vollständig threadsicher. Um Multithreading-Python-Programme zu unterstützen, gibt es eine globale Sperre, den Global Interpreter Lock oder GIL, die vom aktuellen Thread gehalten werden muss, bevor er sicher auf Python-Objekte zugreifen kann. Ohne die Sperre könnten selbst die einfachsten Operationen in einem Multithreading-Programm Probleme verursachen: Zum Beispiel könnte bei gleichzeitiger Inkrementierung des Referenzzählers desselben Objekts durch zwei Threads der Referenzzähler nur einmal statt zweimal inkrementiert werden.

Daher gilt die Regel, dass nur der Thread, der den GIL erworben hat, auf Python-Objekte zugreifen oder Python/C API-Funktionen aufrufen darf. Um die Ausführungskonkurrenz zu emulieren, versucht der Interpreter regelmäßig, Threads zu wechseln (siehe sys.setswitchinterval()). Die Sperre wird auch um potenziell blockierende E/A-Operationen wie das Lesen oder Schreiben einer Datei freigegeben, damit andere Python-Threads in der Zwischenzeit laufen können.

Der Python-Interpreter speichert einige Thread-spezifische Buchhaltungsinformationen in einer Datenstruktur namens PyThreadState, bekannt als Thread-Status. Jeder OS-Thread hat einen Thread-lokalen Zeiger auf einen PyThreadState; ein Thread-Status, auf den dieser Zeiger verweist, gilt als angehängt.

Ein Thread kann zu einem Zeitpunkt nur einen angehängten Thread-Status haben. Ein angehängter Thread-Status ist typischerweise analog zum Halten des GIL, außer bei free-threaded Builds. Bei Builds mit aktiviertem GIL blockiert das Anhängen eines Thread-Status, bis der GIL erworben werden kann. Aber selbst bei Builds ohne GIL ist ein angehängter Thread-Status erforderlich, um die meisten C-APIs aufrufen zu können.

Im Allgemeinen wird beim Verwenden der Python C API immer ein angehängter Thread-Status vorhanden sein. Nur in einigen spezifischen Fällen (wie z.B. in einem Py_BEGIN_ALLOW_THREADS Block) hat der Thread keinen angehängten Thread-Status. Wenn Sie unsicher sind, prüfen Sie, ob PyThreadState_GetUnchecked() NULL zurückgibt.

Detach des Thread-Status aus Erweiterungscode

Die meisten Erweiterungscodes, die den Thread-Status manipulieren, haben die folgende einfache Struktur

Save the thread state in a local variable.
... Do some blocking I/O operation ...
Restore the thread state from the local variable.

Dies ist so üblich, dass ein Paar Makros existiert, um es zu vereinfachen

Py_BEGIN_ALLOW_THREADS
... Do some blocking I/O operation ...
Py_END_ALLOW_THREADS

Das Makro Py_BEGIN_ALLOW_THREADS öffnet einen neuen Block und deklariert eine versteckte lokale Variable; das Makro Py_END_ALLOW_THREADS schließt den Block.

Der obige Block wird zu folgendem Code erweitert

PyThreadState *_save;

_save = PyEval_SaveThread();
... Do some blocking I/O operation ...
PyEval_RestoreThread(_save);

Hier wird erklärt, wie diese Funktionen funktionieren

Der angehängte Thread-Status hält den GIL für den gesamten Interpreter. Beim Detachen des angehängten Thread-Status wird der GIL freigegeben, was anderen Threads erlaubt, einen Thread-Status an ihren eigenen Thread anzuhängen, um somit den GIL zu erhalten und mit der Ausführung zu beginnen. Der Zeiger auf den vorherigen angehängten Thread-Status wird als lokale Variable gespeichert. Beim Erreichen von Py_END_ALLOW_THREADS wird der zuvor angehängte Thread-Status an PyEval_RestoreThread() übergeben. Diese Funktion blockiert, bis ein anderer seinen Thread-Status freigibt, wodurch der alte Thread-Status wieder angehängt werden kann und die C API erneut aufgerufen werden kann.

Für free-threaded Builds ist der GIL normalerweise nicht relevant, aber das Detachen des Thread-Status ist immer noch für blockierende E/A und lange Operationen erforderlich. Der Unterschied besteht darin, dass Threads nicht auf die Freigabe des GIL warten müssen, um ihren Thread-Status anzuhängen, was echte Multi-Core-Parallelität ermöglicht.

Hinweis

Das Aufrufen von System-E/A-Funktionen ist der häufigste Anwendungsfall für das Detachen des Thread-Status, es kann aber auch nützlich sein, bevor lang laufende Berechnungen aufgerufen werden, die keinen Zugriff auf Python-Objekte benötigen, wie z.B. Komprimierungs- oder kryptografische Funktionen, die über Speicherpuffer arbeiten. So lösen beispielsweise die Standardmodule zlib und hashlib den Thread-Status beim Komprimieren oder Hashing von Daten.

Nicht von Python erstellte Threads

Wenn Threads über die dedizierten Python-APIs (wie das threading-Modul) erstellt werden, wird ihnen automatisch ein Thread-Status zugeordnet, und der oben gezeigte Code ist daher korrekt. Wenn Threads jedoch aus C erstellt werden (z.B. von einer Drittanbieterbibliothek mit eigenem Thread-Management), halten sie den GIL nicht, da sie keinen angehängten Thread-Status haben.

Wenn Sie Python-Code von diesen Threads aus aufrufen müssen (was oft Teil einer Callback-API ist, die von der oben genannten Drittanbieterbibliothek bereitgestellt wird), müssen Sie diese Threads zuerst beim Interpreter registrieren, indem Sie einen angehängten Thread-Status erstellen, bevor Sie die Python/C API verwenden können. Wenn Sie fertig sind, sollten Sie den Thread-Status detachen und ihn schließlich freigeben.

Die Funktionen PyGILState_Ensure() und PyGILState_Release() erledigen all dies automatisch. Das typische Idiom für den Aufruf von Python aus einem C-Thread ist

PyGILState_STATE gstate;
gstate = PyGILState_Ensure();

/* Perform Python actions here. */
result = CallSomeFunction();
/* evaluate result or handle exception */

/* Release the thread. No Python API allowed beyond this point. */
PyGILState_Release(gstate);

Beachten Sie, dass die PyGILState_*-Funktionen davon ausgehen, dass es nur einen globalen Interpreter gibt (der automatisch von Py_Initialize() erstellt wird). Python unterstützt die Erstellung zusätzlicher Interpreter (mit Py_NewInterpreter()), aber die Mischung mehrerer Interpreter und der PyGILState_* API wird nicht unterstützt. Dies liegt daran, dass PyGILState_Ensure() und ähnliche Funktionen standardmäßig einen Thread-Status für den Hauptinterpreter anhängen, was bedeutet, dass der Thread nicht sicher mit dem aufrufenden Subinterpreter interagieren kann.

Unterstützung von Subinterpretern in Nicht-Python-Threads

Wenn Sie Subinterpreter mit Nicht-Python-erstellten Threads unterstützen möchten, müssen Sie die PyThreadState_* API anstelle der traditionellen PyGILState_* API verwenden.

Insbesondere müssen Sie den Interpreter-Status aus der aufrufenden Funktion speichern und ihn an PyThreadState_New() übergeben, was sicherstellt, dass der Thread-Status auf den richtigen Interpreter zielt

/* The return value of PyInterpreterState_Get() from the
   function that created this thread. */
PyInterpreterState *interp = ThreadData->interp;
PyThreadState *tstate = PyThreadState_New(interp);
PyThreadState_Swap(tstate);

/* GIL of the subinterpreter is now held.
   Perform Python actions here. */
result = CallSomeFunction();
/* evaluate result or handle exception */

/* Destroy the thread state. No Python API allowed beyond this point. */
PyThreadState_Clear(tstate);
PyThreadState_DeleteCurrent();

Vorsichtsmaßnahmen bezüglich fork()

Eine weitere wichtige Anmerkung zu Threads ist ihr Verhalten im Angesicht des C-Aufrufs fork(). Auf den meisten Systemen mit fork() existiert nach dem Forken eines Prozesses nur der Thread, der den Fork-Aufruf getätigt hat. Dies hat konkrete Auswirkungen sowohl auf die Handhabung von Sperren als auch auf alle gespeicherten Zustände in CPythons Laufzeitumgebung.

Die Tatsache, dass nur der "aktuelle" Thread übrig bleibt, bedeutet, dass alle von anderen Threads gehaltenen Sperren nie freigegeben werden. Python löst dies für os.fork(), indem es seine internen Sperren vor dem Fork erwirbt und sie danach freigibt. Zusätzlich setzt es alle Lock-Objekte im Kindprozess zurück. Beim Erweitern oder Einbetten von Python gibt es keine Möglichkeit, Python über zusätzliche (nicht-Python-)Sperren zu informieren, die vor oder nach einem Fork erworben oder zurückgesetzt werden müssen. Betriebssystemfunktionen wie pthread_atfork() müssten verwendet werden, um dasselbe zu erreichen. Darüber hinaus kann beim Erweitern oder Einbetten von Python das direkte Aufrufen von fork() anstatt über os.fork() (und Rückkehr zu oder Aufruf von Python) zu einem Deadlock führen, da eine der internen Sperren von Python von einem Thread gehalten wird, der nach dem Fork veraltet ist. PyOS_AfterFork_Child() versucht, die notwendigen Sperren zurückzusetzen, ist aber nicht immer in der Lage dazu.

Die Tatsache, dass alle anderen Threads verschwinden, bedeutet auch, dass der Laufzeitstatus von CPython dort ordnungsgemäß bereinigt werden muss, was os.fork() tut. Dies beinhaltet die Finalisierung aller anderen PyThreadState-Objekte, die zum aktuellen Interpreter gehören, und aller anderen PyInterpreterState-Objekte. Aufgrund dessen und der besonderen Natur des "Hauptinterpreters" sollte fork() nur im "Hauptthread" dieses Interpreters aufgerufen werden, wo die CPython-globale Laufzeitumgebung ursprünglich initialisiert wurde. Die einzige Ausnahme ist, wenn unmittelbar danach exec() aufgerufen wird.

Vorsichtsmaßnahmen bezüglich der Laufzeitfinalisierung

Im späten Stadium der Interpreter-Abschaltung, nach dem Versuch, auf den Abschluss von Nicht-Daemon-Threads zu warten (obwohl dies durch KeyboardInterrupt unterbrochen werden kann) und dem Ausführen der atexit-Funktionen, wird die Laufzeitumgebung als *finalisierend* markiert: Py_IsFinalizing() und sys.is_finalizing() geben true zurück. Zu diesem Zeitpunkt darf nur der *Finalisierungs-Thread*, der die Finalisierung initiiert hat (typischerweise der Hauptthread), den GIL erwerben.

Wenn ein Thread, außer dem Finalisierungs-Thread, während der Finalisierung versucht, einen Thread-Status anzuhängen, sei es explizit oder implizit, tritt der Thread in einen **dauerhaft blockierten Zustand** ein, in dem er verbleibt, bis das Programm beendet wird. In den meisten Fällen ist dies harmlos, kann aber zu einem Deadlock führen, wenn eine spätere Stufe der Finalisierung versucht, eine Sperre zu erwerben, die dem blockierten Thread gehört, oder anderweitig auf den blockierten Thread wartet.

Brutal? Ja. Dies verhindert zufällige Abstürze und/oder unerwartet übersprungene C++-Finalisierungen weiter oben im Call Stack, wenn solche Threads in CPython 3.13 und früher zwangsweise beendet wurden. Die CPython-Laufzeit-Thread-Status-C-APIs hatten nie Erwartungen an Fehlerberichterstattung oder -behandlung beim Thread-Status-Anhängen, die eine anständige Beendigung aus dieser Situation ermöglicht hätten. Die Änderung dessen würde neue stabile C-APIs erfordern und den Großteil des C-Codes im CPython-Ökosystem umschreiben, um diese mit Fehlerbehandlung zu verwenden.

High-Level API

Dies sind die am häufigsten verwendeten Typen und Funktionen beim Schreiben von C-Erweiterungscode oder beim Einbetten des Python-Interpreters

type PyInterpreterState
Teil der Limited API (als opaker Struct).

Diese Datenstruktur repräsentiert den Status, der von einer Reihe kooperierender Threads gemeinsam genutzt wird. Threads, die zu demselben Interpreter gehören, teilen sich ihre Modulverwaltung und einige andere interne Elemente. Es gibt keine öffentlichen Member in dieser Struktur.

Threads, die zu verschiedenen Interpretern gehören, teilen sich anfänglich nichts außer dem Prozessstatus wie verfügbarem Speicher, offenen Dateideskriptoren und Ähnlichem. Der globale Interpreter-Lock wird ebenfalls von allen Threads gemeinsam genutzt, unabhängig davon, zu welchem Interpreter sie gehören.

Geändert in Version 3.12: PEP 684 führte die Möglichkeit eines per-Interpreter-GIL ein. Siehe Py_NewInterpreterFromConfig().

type PyThreadState
Teil der Limited API (als opaker Struct).

Diese Datenstruktur repräsentiert den Status eines einzelnen Threads. Der einzige öffentliche Datenmember ist

PyInterpreterState *interp

Der Interpreter-Status dieses Threads.

void PyEval_InitThreads()
Teil der Stable ABI.

Veraltete Funktion, die nichts tut.

In Python 3.6 und älter erstellte diese Funktion den GIL, wenn er noch nicht existierte.

Geändert in Version 3.9: Die Funktion tut jetzt nichts mehr.

Geändert in Version 3.7: Diese Funktion wird jetzt von Py_Initialize() aufgerufen, sodass Sie sie nicht mehr selbst aufrufen müssen.

Geändert in Version 3.2: Diese Funktion kann nicht mehr vor Py_Initialize() aufgerufen werden.

Seit Version 3.9 veraltet.

PyThreadState *PyEval_SaveThread()
Teil der Stable ABI.

Detacht den angehängten Thread-Status und gibt ihn zurück. Der Thread hat nach der Rückgabe keinen Thread-Status mehr.

void PyEval_RestoreThread(PyThreadState *tstate)
Teil der Stable ABI.

Setzt den angehängten Thread-Status auf *tstate*. Der übergebene Thread-Status **darf nicht** angehängt sein, sonst kommt es zu einem Deadlock. *tstate* wird nach der Rückgabe angehängt.

Hinweis

Das Aufrufen dieser Funktion von einem Thread aus, wenn die Laufzeitumgebung finalisiert wird, blockiert den Thread, bis das Programm beendet wird, auch wenn der Thread nicht von Python erstellt wurde. Siehe Vorsichtsmaßnahmen bezüglich der Laufzeitfinalisierung für weitere Details.

Geändert in Version 3.14: Blockiert den aktuellen Thread, anstatt ihn zu beenden, wenn er während der Finalisierung des Interpreters aufgerufen wird.

PyThreadState *PyThreadState_Get()
Teil der Stable ABI.

Gibt den angehängten Thread-Status zurück. Wenn der Thread keinen angehängten Thread-Status hat (z.B. innerhalb eines Py_BEGIN_ALLOW_THREADS Blocks), führt dies zu einem fatalen Fehler (sodass der Aufrufer nicht auf NULL prüfen muss).

Siehe auch PyThreadState_GetUnchecked().

PyThreadState *PyThreadState_GetUnchecked()

Ähnlich wie PyThreadState_Get(), aber tötet den Prozess nicht mit einem fatalen Fehler, wenn es NULL ist. Der Aufrufer ist dafür verantwortlich zu prüfen, ob das Ergebnis NULL ist.

Hinzugefügt in Version 3.13: In Python 3.5 bis 3.12 war die Funktion privat und hieß _PyThreadState_UncheckedGet().

PyThreadState *PyThreadState_Swap(PyThreadState *tstate)
Teil der Stable ABI.

Setzt den Thread-Status auf tstate und gibt den vorher angehängten Thread-Status zurück.

Diese Funktion kann sicher aufgerufen werden, ohne dass ein Thread-Status angehängt ist. Sie gibt einfach NULL zurück, was bedeutet, dass kein vorheriger Thread-Status vorhanden war.

Hinweis

Ähnlich wie PyGILState_Ensure() wird diese Funktion den Thread blockieren, wenn die Laufzeitumgebung finalisiert wird.

Die folgenden Funktionen verwenden Thread-lokalen Speicher und sind nicht mit Sub-Interpretern kompatibel

type PyGILState_STATE
Teil der Stable ABI.

Der Typ des von PyGILState_Ensure() zurückgegebenen und an PyGILState_Release() übergebenen Werts.

enumerator PyGILState_LOCKED

Der GIL wurde bereits gehalten, als PyGILState_Ensure() aufgerufen wurde.

enumerator PyGILState_UNLOCKED

Der GIL wurde nicht gehalten, als PyGILState_Ensure() aufgerufen wurde.

PyGILState_STATE PyGILState_Ensure()
Teil der Stable ABI.

Stellt sicher, dass der aktuelle Thread bereit ist, die Python C API aufzurufen, unabhängig vom aktuellen Zustand von Python oder dem Thread-Status. Dies kann beliebig oft von einem Thread aufgerufen werden, solange jeder Aufruf mit einem Aufruf von PyGILState_Release() abgeglichen wird. Im Allgemeinen können andere Thread-bezogene APIs zwischen Aufrufen von PyGILState_Ensure() und PyGILState_Release() verwendet werden, solange der Thread-Status vor dem Release() in seinen vorherigen Zustand zurückversetzt wird. Beispielsweise ist die normale Verwendung der Makros Py_BEGIN_ALLOW_THREADS und Py_END_ALLOW_THREADS akzeptabel.

Der Rückgabewert ist ein undurchsichtiger „Handle“ für den Thread-Status, als PyGILState_Ensure() aufgerufen wurde, und muss an PyGILState_Release() übergeben werden, um sicherzustellen, dass Python im gleichen Zustand hinterlassen wird. Obwohl rekursive Aufrufe erlaubt sind, dürfen diese Handles *nicht* geteilt werden – jeder eindeutige Aufruf von PyGILState_Ensure() muss das Handle für seinen Aufruf von PyGILState_Release() speichern.

Wenn die Funktion zurückkehrt, wird ein Thread-Status vorhanden sein und der Thread kann beliebigen Python-Code ausführen. Ein Fehler ist ein fataler Fehler.

Warnung

Der Aufruf dieser Funktion während der Finalisierung der Laufzeitumgebung ist unsicher. Dies führt entweder dazu, dass der Thread blockiert, bis das Programm endet, oder in seltenen Fällen den Interpreter vollständig zum Absturz bringt. Weitere Details finden Sie unter Vorsichtsmaßnahmen bei der Laufzeitfinalisierung.

Geändert in Version 3.14: Blockiert den aktuellen Thread, anstatt ihn zu beenden, wenn er während der Finalisierung des Interpreters aufgerufen wird.

void PyGILState_Release(PyGILState_STATE)
Teil der Stable ABI.

Gibt alle zuvor erworbenen Ressourcen frei. Nach diesem Aufruf ist der Zustand von Python derselbe wie vor dem entsprechenden Aufruf von PyGILState_Ensure() (aber im Allgemeinen wird dieser Zustand dem Aufrufer unbekannt sein, daher die Verwendung der GILState-API).

Jeder Aufruf von PyGILState_Ensure() muss durch einen Aufruf von PyGILState_Release() auf demselben Thread abgeglichen werden.

PyThreadState *PyGILState_GetThisThreadState()
Teil der Stable ABI.

Ruft den Thread-Status für diesen Thread ab. Gibt möglicherweise NULL zurück, wenn noch keine GILState-API auf dem aktuellen Thread verwendet wurde. Beachten Sie, dass der Hauptthread immer einen solchen Thread-Status hat, auch wenn keine Auto-Thread-Status-Aufrufe auf dem Hauptthread gemacht wurden. Dies ist hauptsächlich eine Hilfs-/Diagnosefunktion.

Hinweis

Diese Funktion kann auch dann einen Wert ungleich NULL zurückgeben, wenn der Thread-Status getrennt ist. Bevorzugen Sie für die meisten Fälle PyThreadState_Get() oder PyThreadState_GetUnchecked().

Siehe auch

PyThreadState_Get()

int PyGILState_Check()

Gibt 1 zurück, wenn der aktuelle Thread den GIL hält, und 0 andernfalls. Diese Funktion kann von jedem Thread zu jeder Zeit aufgerufen werden. Nur wenn sein Thread-Status über PyGILState_Ensure() initialisiert wurde, gibt er 1 zurück. Dies ist hauptsächlich eine Hilfs-/Diagnosefunktion. Sie kann beispielsweise in Callback-Kontexten oder Speicherallokationsfunktionen nützlich sein, wenn das Wissen, dass der GIL gesperrt ist, dem Aufrufer erlaubt, sensible Aktionen durchzuführen oder sich anders zu verhalten.

Hinweis

Wenn der aktuelle Python-Prozess jemals einen Sub-Interpreter erstellt hat, gibt diese Funktion *immer* 1 zurück. Bevorzugen Sie für die meisten Fälle PyThreadState_GetUnchecked().

Hinzugefügt in Version 3.4.

Die folgenden Makros werden normalerweise ohne abschließendes Semikolon verwendet; Beispiele finden Sie im Python-Quellcode.

Py_BEGIN_ALLOW_THREADS
Teil der Stable ABI.

Dieses Makro expandiert zu { PyThreadState *_save; _save = PyEval_SaveThread();. Beachten Sie, dass es eine öffnende geschweifte Klammer enthält; es muss mit einem folgenden Makro Py_END_ALLOW_THREADS abgeglichen werden. Siehe oben für weitere Diskussionen über dieses Makro.

Py_END_ALLOW_THREADS
Teil der Stable ABI.

Dieses Makro expandiert zu PyEval_RestoreThread(_save); }. Beachten Sie, dass es eine schließende geschweifte Klammer enthält; es muss mit einem früheren Makro Py_BEGIN_ALLOW_THREADS abgeglichen werden. Siehe oben für weitere Diskussionen über dieses Makro.

Py_BLOCK_THREADS
Teil der Stable ABI.

Dieses Makro expandiert zu PyEval_RestoreThread(_save);: es ist äquivalent zu Py_END_ALLOW_THREADS ohne die schließende Klammer.

Py_UNBLOCK_THREADS
Teil der Stable ABI.

Dieses Makro expandiert zu _save = PyEval_SaveThread();: es ist äquivalent zu Py_BEGIN_ALLOW_THREADS ohne die öffnende Klammer und die Variablendeklaration.

Low-Level API

Alle folgenden Funktionen müssen nach Py_Initialize() aufgerufen werden.

Geändert in Version 3.7: Py_Initialize() initialisiert nun den GIL und setzt einen angehängten Thread-Status.

PyInterpreterState *PyInterpreterState_New()
Teil der Stable ABI.

Erstellt ein neues Interpreter-Zustandsobjekt. Ein Thread-Status ist nicht erforderlich, kann aber optional vorhanden sein, wenn Aufrufe dieser Funktion serialisiert werden müssen.

Löst ein Auditing-Ereignis cpython.PyInterpreterState_New ohne Argumente aus.

void PyInterpreterState_Clear(PyInterpreterState *interp)
Teil der Stable ABI.

Setzt alle Informationen in einem Interpreter-Zustandsobjekt zurück. Für den Interpreter muss ein Thread-Status angehängt sein.

Löst ein Auditing-Ereignis cpython.PyInterpreterState_Clear ohne Argumente aus.

void PyInterpreterState_Delete(PyInterpreterState *interp)
Teil der Stable ABI.

Zerstört ein Interpreter-Zustandsobjekt. Für den Zielinterpreter darf *kein* Thread-Status angehängt sein. Der Interpreter-Status muss mit einem vorherigen Aufruf von PyInterpreterState_Clear() zurückgesetzt worden sein.

PyThreadState *PyThreadState_New(PyInterpreterState *interp)
Teil der Stable ABI.

Erstellt ein neues Thread-Zustandsobjekt, das zum angegebenen Interpreter-Objekt gehört. Ein Thread-Status ist nicht erforderlich.

void PyThreadState_Clear(PyThreadState *tstate)
Teil der Stable ABI.

Setzt alle Informationen in einem Thread-Status-Objekt zurück. tstate muss angehängt sein.

Geändert in Version 3.9: Diese Funktion ruft nun den Callback PyThreadState.on_delete auf. Zuvor geschah dies in PyThreadState_Delete().

Geändert in Version 3.13: Der Callback PyThreadState.on_delete wurde entfernt.

void PyThreadState_Delete(PyThreadState *tstate)
Teil der Stable ABI.

Zerstört ein Thread-Status-Objekt. tstate sollte an keinen Thread angehängt sein. tstate muss mit einem vorherigen Aufruf von PyThreadState_Clear() zurückgesetzt worden sein.

void PyThreadState_DeleteCurrent(void)

Löst den angehängten Thread-Status (der mit einem vorherigen Aufruf von PyThreadState_Clear() zurückgesetzt worden sein muss) und zerstört ihn dann.

Nach der Rückgabe wird kein Thread-Status angehängt sein.

PyFrameObject *PyThreadState_GetFrame(PyThreadState *tstate)
Teil der Stable ABI seit Version 3.10.

Ruft den aktuellen Frame des Python-Thread-Status tstate ab.

Gibt eine starke Referenz zurück. Gibt NULL zurück, wenn kein Frame gerade ausgeführt wird.

Siehe auch PyEval_GetFrame().

tstate darf nicht NULL sein und muss angehängt sein.

Hinzugefügt in Version 3.9.

uint64_t PyThreadState_GetID(PyThreadState *tstate)
Teil der Stable ABI seit Version 3.10.

Ruft die eindeutige Thread-Status-ID des Python-Thread-Status tstate ab.

tstate darf nicht NULL sein und muss angehängt sein.

Hinzugefügt in Version 3.9.

PyInterpreterState *PyThreadState_GetInterpreter(PyThreadState *tstate)
Teil der Stable ABI seit Version 3.10.

Ruft den Interpreter des Python-Thread-Status tstate ab.

tstate darf nicht NULL sein und muss angehängt sein.

Hinzugefügt in Version 3.9.

void PyThreadState_EnterTracing(PyThreadState *tstate)

Suspendiert das Tracing und Profiling im Python-Thread-Status tstate.

Setzt sie mit der Funktion PyThreadState_LeaveTracing() fort.

Hinzugefügt in Version 3.11.

void PyThreadState_LeaveTracing(PyThreadState *tstate)

Setzt das Tracing und Profiling im Python-Thread-Status tstate fort, das von der Funktion PyThreadState_EnterTracing() suspendiert wurde.

Siehe auch die Funktionen PyEval_SetTrace() und PyEval_SetProfile().

Hinzugefügt in Version 3.11.

PyInterpreterState *PyInterpreterState_Get(void)
Teil der Stable ABI seit Version 3.9.

Ruft den aktuellen Interpreter ab.

Gibt einen fatalen Fehler aus, wenn kein Thread-Status angehängt ist. Es kann nicht NULL zurückgeben.

Hinzugefügt in Version 3.9.

int64_t PyInterpreterState_GetID(PyInterpreterState *interp)
Teil der Stable ABI seit Version 3.7.

Gibt die eindeutige ID des Interpreters zurück. Wenn ein Fehler aufgetreten ist, wird -1 zurückgegeben und ein Fehler gesetzt.

Der Aufrufer muss einen Thread-Status angehängt haben.

Hinzugefügt in Version 3.7.

PyObject *PyInterpreterState_GetDict(PyInterpreterState *interp)
Rückgabewert: Geliehene Referenz. Teil der Stable ABI seit Version 3.8.

Gibt ein Wörterbuch zurück, in dem interpreterspezifische Daten gespeichert werden können. Wenn diese Funktion NULL zurückgibt, wurde keine Ausnahme ausgelöst und der Aufrufer sollte davon ausgehen, dass kein interpreterspezifisches Wörterbuch verfügbar ist.

Dies ist kein Ersatz für PyModule_GetState(), das Erweiterungen verwenden sollten, um interpreterspezifische Zustandsinformationen zu speichern.

Das zurückgegebene Wörterbuch wird vom Interpreter geliehen und ist bis zum Ende des Interpreters gültig.

Hinzugefügt in Version 3.8.

typedef PyObject *(*_PyFrameEvalFunction)(PyThreadState *tstate, _PyInterpreterFrame *frame, int throwflag)

Typ einer Frame-Evaluierungsfunktion.

Der Parameter throwflag wird von der Methode throw() von Generatoren verwendet: Wenn er ungleich Null ist, wird die aktuelle Ausnahme behandelt.

Geändert in Version 3.9: Die Funktion nimmt jetzt einen tstate-Parameter entgegen.

Geändert in Version 3.11: Der frame-Parameter wurde von PyFrameObject* zu _PyInterpreterFrame* geändert.

_PyFrameEvalFunction _PyInterpreterState_GetEvalFrameFunc(PyInterpreterState *interp)

Ruft die Frame-Evaluierungsfunktion ab.

Siehe PEP 523 „Hinzufügen einer Frame-Evaluierungs-API zu CPython“.

Hinzugefügt in Version 3.9.

void _PyInterpreterState_SetEvalFrameFunc(PyInterpreterState *interp, _PyFrameEvalFunction eval_frame)

Setzt die Frame-Evaluierungsfunktion.

Siehe PEP 523 „Hinzufügen einer Frame-Evaluierungs-API zu CPython“.

Hinzugefügt in Version 3.9.

PyObject *PyThreadState_GetDict()
Rückgabewert: Ausgeliehene Referenz. Teil der Stable ABI.

Gibt ein Wörterbuch zurück, in dem Erweiterungen threadspezifische Zustandsinformationen speichern können. Jede Erweiterung sollte einen eindeutigen Schlüssel verwenden, um den Zustand im Wörterbuch zu speichern. Es ist in Ordnung, diese Funktion aufzurufen, wenn kein Thread-Status angehängt ist. Wenn diese Funktion NULL zurückgibt, wurde keine Ausnahme ausgelöst und der Aufrufer sollte davon ausgehen, dass kein Thread-Status angehängt ist.

int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
Teil der Stable ABI.

Löst asynchron eine Ausnahme in einem Thread aus. Das Argument id ist die Thread-ID des Zielthreads; exc ist das auszulösende Ausnahmeobjekt. Diese Funktion stiehlt keine Referenzen auf exc. Um naive Fehlverwendung zu verhindern, müssen Sie Ihre eigene C-Erweiterung schreiben, um diese Funktion aufzurufen. Muss mit einem angehängten Thread-Status aufgerufen werden. Gibt die Anzahl der geänderten Thread-Status zurück; dies ist normalerweise eins, aber null, wenn die Thread-ID nicht gefunden wird. Wenn exc NULL ist, wird die ausstehende Ausnahme (falls vorhanden) für den Thread gelöscht. Dies löst keine Ausnahmen aus.

Geändert in Version 3.7: Der Typ des Parameters id wurde von long zu unsigned long geändert.

void PyEval_AcquireThread(PyThreadState *tstate)
Teil der Stable ABI.

Hängen Sie tstate an den aktuellen Thread an, der nicht NULL oder bereits angehängt sein darf.

Der aufrufende Thread darf keinen angehängten Thread-Zustand besitzen.

Hinweis

Das Aufrufen dieser Funktion von einem Thread aus, wenn die Laufzeitumgebung finalisiert wird, blockiert den Thread, bis das Programm beendet wird, auch wenn der Thread nicht von Python erstellt wurde. Siehe Vorsichtsmaßnahmen bezüglich der Laufzeitfinalisierung für weitere Details.

Geändert in Version 3.8: Aktualisiert, um konsistent mit PyEval_RestoreThread(), Py_END_ALLOW_THREADS() und PyGILState_Ensure() zu sein, und terminiert den aktuellen Thread, wenn er während der Finalisierung des Interpreters aufgerufen wird.

Geändert in Version 3.14: Blockiert den aktuellen Thread, anstatt ihn zu beenden, wenn er während der Finalisierung des Interpreters aufgerufen wird.

PyEval_RestoreThread() ist eine Funktion auf höherer Ebene, die immer verfügbar ist (auch wenn Threads noch nicht initialisiert wurden).

void PyEval_ReleaseThread(PyThreadState *tstate)
Teil der Stable ABI.

Löst den angehängten Thread-Zustand. Das Argument tstate, das nicht NULL sein darf, wird nur verwendet, um zu überprüfen, ob es den angehängten Thread-Zustand repräsentiert – wenn nicht, wird ein schwerwiegender Fehler gemeldet.

PyEval_SaveThread() ist eine Funktion auf höherer Ebene, die immer verfügbar ist (auch wenn Threads noch nicht initialisiert wurden).

Sub-Interpreter-Unterstützung

Obwohl Sie in den meisten Fällen nur einen einzigen Python-Interpreter einbetten, gibt es Fälle, in denen Sie mehrere unabhängige Interpreter im selben Prozess und vielleicht sogar im selben Thread erstellen müssen. Sub-Interpreter ermöglichen Ihnen dies.

Der „Haupt“-Interpreter ist der erste, der bei der Initialisierung der Laufzeitumgebung erstellt wird. Er ist normalerweise der einzige Python-Interpreter in einem Prozess. Im Gegensatz zu Sub-Interpretern hat der Haupt-Interpreter eindeutige prozessweite Verantwortlichkeiten wie die Signalbehandlung. Er ist auch für die Ausführung während der Initialisierung der Laufzeitumgebung verantwortlich und ist normalerweise der aktive Interpreter während der Finalisierung der Laufzeitumgebung. Die Funktion PyInterpreterState_Main() gibt einen Zeiger auf seinen Zustand zurück.

Sie können zwischen Sub-Interpretern mit der Funktion PyThreadState_Swap() wechseln. Sie können sie mit den folgenden Funktionen erstellen und zerstören.

type PyInterpreterConfig

Struktur, die die meisten Parameter zur Konfiguration eines Sub-Interpreters enthält. Ihre Werte werden nur in Py_NewInterpreterFromConfig() verwendet und niemals von der Laufzeitumgebung geändert.

Hinzugefügt in Version 3.12.

Strukturfelder

int use_main_obmalloc

Wenn dies 0 ist, verwendet der Sub-Interpreter seinen eigenen „Objekt“-Allocator-Zustand. Andernfalls verwendet er den Zustand des Hauptinterpreters (teilt ihn sich).

Wenn dies 0 ist, muss check_multi_interp_extensions 1 (ungleich Null) sein. Wenn dies 1 ist, darf gil nicht PyInterpreterConfig_OWN_GIL sein.

int allow_fork

Wenn dies 0 ist, unterstützt die Laufzeitumgebung das Forken des Prozesses nicht in einem Thread, in dem der Sub-Interpreter gerade aktiv ist. Andernfalls ist Fork uneingeschränkt.

Beachten Sie, dass das Modul subprocess auch dann funktioniert, wenn Fork verboten ist.

int allow_exec

Wenn dies 0 ist, unterstützt die Laufzeitumgebung das Ersetzen des aktuellen Prozesses durch exec (z. B. os.execv()) nicht in einem Thread, in dem der Sub-Interpreter gerade aktiv ist. Andernfalls ist Exec uneingeschränkt.

Beachten Sie, dass das Modul subprocess auch dann funktioniert, wenn Exec verboten ist.

int allow_threads

Wenn dies 0 ist, erstellt das threading-Modul des Sub-Interpreters keine Threads. Andernfalls sind Threads erlaubt.

int allow_daemon_threads

Wenn dies 0 ist, erstellt das threading-Modul des Sub-Interpreters keine Daemon-Threads. Andernfalls sind Daemon-Threads erlaubt (solange allow_threads ungleich Null ist).

int check_multi_interp_extensions

Wenn dies 0 ist, können alle Erweiterungsmodule importiert werden, einschließlich Legacy-Module (Single-Phase-Init), in jedem Thread, in dem der Sub-Interpreter aktiv ist. Andernfalls dürfen nur Multi-Phase-Init-Erweiterungsmodule (siehe PEP 489) importiert werden. (Siehe auch Py_mod_multiple_interpreters.)

Dies muss 1 (ungleich Null) sein, wenn use_main_obmalloc 0 ist.

int gil

Dies bestimmt die Arbeitsweise des GIL für den Sub-Interpreter. Es kann einer der folgenden Werte sein:

PyInterpreterConfig_DEFAULT_GIL

Verwenden Sie die Standardauswahl (PyInterpreterConfig_SHARED_GIL).

PyInterpreterConfig_SHARED_GIL

Verwenden Sie das GIL des Hauptinterpreters (teilen Sie es sich).

PyInterpreterConfig_OWN_GIL

Verwenden Sie das eigene GIL des Sub-Interpreters.

Wenn dies PyInterpreterConfig_OWN_GIL ist, muss PyInterpreterConfig.use_main_obmalloc 0 sein.

PyStatus Py_NewInterpreterFromConfig(PyThreadState **tstate_p, const PyInterpreterConfig *config)

Erstellt einen neuen Sub-Interpreter. Dies ist eine (fast) völlig separate Umgebung für die Ausführung von Python-Code. Insbesondere hat der neue Interpreter getrennte, unabhängige Versionen aller importierten Module, einschließlich der grundlegenden Module builtins, __main__ und sys. Die Tabelle der geladenen Module (sys.modules) und der Modul-Suchpfad (sys.path) sind ebenfalls getrennt. Die neue Umgebung hat keine Variable sys.argv. Sie hat neue Standard-I/O-Stream-Datei-Objekte sys.stdin, sys.stdout und sys.stderr (diese verweisen jedoch auf dieselben zugrunde liegenden Dateideskriptoren).

Das angegebene config steuert die Optionen, mit denen der Interpreter initialisiert wird.

Bei Erfolg wird tstate_p auf den ersten im neuen Sub-Interpreter erstellten Thread-Zustand gesetzt. Dieser Thread-Zustand ist angehängt. Beachten Sie, dass kein tatsächlicher Thread erstellt wird; siehe die Diskussion über Thread-Zustände unten. Wenn die Erstellung des neuen Interpreters fehlschlägt, wird tstate_p auf NULL gesetzt; es wird keine Ausnahme gesetzt, da der Ausnahmezustand im angehängten Thread-Zustand gespeichert wird, der möglicherweise nicht existiert.

Wie alle anderen Python/C-API-Funktionen muss ein angehängter Thread-Zustand vorhanden sein, bevor diese Funktion aufgerufen wird, aber er kann beim Zurückkehren abgetrennt werden. Bei Erfolg ist der zurückgegebene Thread-Zustand angehängt. Wenn der Sub-Interpreter mit seinem eigenen GIL erstellt wird, wird der angehängte Thread-Zustand des aufrufenden Interpreters abgetrennt. Wenn die Funktion zurückkehrt, ist der Thread-Zustand des neuen Interpreters an den aktuellen Thread angehängt und der angehängte Thread-Zustand des vorherigen Interpreters bleibt abgetrennt.

Hinzugefügt in Version 3.12.

Sub-Interpreter sind am effektivsten, wenn sie voneinander isoliert sind und bestimmte Funktionalitäten eingeschränkt sind.

PyInterpreterConfig config = {
    .use_main_obmalloc = 0,
    .allow_fork = 0,
    .allow_exec = 0,
    .allow_threads = 1,
    .allow_daemon_threads = 0,
    .check_multi_interp_extensions = 1,
    .gil = PyInterpreterConfig_OWN_GIL,
};
PyThreadState *tstate = NULL;
PyStatus status = Py_NewInterpreterFromConfig(&tstate, &config);
if (PyStatus_Exception(status)) {
    Py_ExitStatusException(status);
}

Beachten Sie, dass die Konfiguration nur kurz verwendet wird und nicht geändert wird. Während der Initialisierung werden die Werte der Konfiguration in verschiedene PyInterpreterState-Werte umgewandelt. Eine schreibgeschützte Kopie der Konfiguration kann intern im PyInterpreterState gespeichert werden.

Erweiterungsmodule werden zwischen (Sub-)Interpretern wie folgt geteilt:

  • Für Module, die Multi-Phase-Initialisierung verwenden, z. B. PyModule_FromDefAndSpec(), wird für jeden Interpreter ein separates Modulobjekt erstellt und initialisiert. Nur C-Level-statische und globale Variablen werden zwischen diesen Modulobjekten geteilt.

  • Für Module, die Single-Phase-Initialisierung verwenden, z. B. PyModule_Create(), wird beim ersten Import eines bestimmten Erweiterungsmoduls dieses normal initialisiert und eine (flache) Kopie seines Modulwörterbuchs wird beiseitegelegt. Wenn dasselbe Erweiterungsmodul von einem anderen (Sub-)Interpreter importiert wird, wird ein neues Modul initialisiert und mit dem Inhalt dieser Kopie gefüllt; die init-Funktion der Erweiterung wird nicht aufgerufen. Objekte im Modulwörterbuch werden somit zwischen (Sub-)Interpretern geteilt, was zu unerwünschtem Verhalten führen kann (siehe Bugs und Hinweise unten).

    Beachten Sie, dass dies anders ist als bei einem Import eines Erweiterungsmoduls, nachdem der Interpreter durch Aufruf von Py_FinalizeEx() und Py_Initialize() vollständig neu initialisiert wurde; in diesem Fall *wird* die initmodule-Funktion der Erweiterung erneut aufgerufen. Wie bei der Multi-Phase-Initialisierung bedeutet dies, dass nur C-Level-statische und globale Variablen zwischen diesen Modulen geteilt werden.

PyThreadState *Py_NewInterpreter(void)
Teil der Stable ABI.

Erstellt einen neuen Sub-Interpreter. Dies ist im Wesentlichen nur ein Wrapper um Py_NewInterpreterFromConfig() mit einer Konfiguration, die das bestehende Verhalten beibehält. Das Ergebnis ist ein nicht isolierter Sub-Interpreter, der das GIL des Hauptinterpreters teilt, Fork/Exec zulässt, Daemon-Threads zulässt und Single-Phase-Init-Module erlaubt.

void Py_EndInterpreter(PyThreadState *tstate)
Teil der Stable ABI.

Zerstört den (Sub-)Interpreter, der durch den gegebenen Thread-Zustand repräsentiert wird. Der gegebene Thread-Zustand muss angehängt sein. Wenn der Aufruf zurückkehrt, wird kein angehängter Thread-Zustand mehr vorhanden sein. Alle mit diesem Interpreter verbundenen Thread-Zustände werden zerstört.

Py_FinalizeEx() zerstört alle Sub-Interpreter, die zu diesem Zeitpunkt nicht explizit zerstört wurden.

Ein GIL pro Interpreter

Mit Py_NewInterpreterFromConfig() können Sie einen Sub-Interpreter erstellen, der vollständig von anderen Interpretern isoliert ist, einschließlich eines eigenen GIL. Der wichtigste Vorteil dieser Isolation ist, dass ein solcher Interpreter Python-Code ausführen kann, ohne von anderen Interpretern blockiert zu werden oder andere zu blockieren. Ein einzelner Python-Prozess kann somit wirklich von mehreren CPU-Kernen bei der Ausführung von Python-Code profitieren. Die Isolation fördert auch einen anderen Ansatz zur Nebenläufigkeit als nur die Verwendung von Threads. (Siehe PEP 554 und PEP 684.)

Die Verwendung eines isolierten Interpreters erfordert Wachsamkeit bei der Aufrechterhaltung dieser Isolation. Das bedeutet insbesondere, keine Objekte oder veränderlichen Zustand ohne Garantien für Threadsicherheit zu teilen. Selbst Objekte, die ansonsten unveränderlich sind (z. B. None, (1, 5)) können aufgrund der Referenzzählung normalerweise nicht geteilt werden. Ein einfacher, aber weniger effizienter Ansatz hierfür ist die Verwendung eines globalen Sperrmechanismus für die gesamte Nutzung eines Zustands (oder Objekts). Alternativ können effektiv unveränderliche Objekte (wie ganze Zahlen oder Zeichenketten) trotz ihrer Referenzzählungen sicher gemacht werden, indem sie unsterblich gemacht werden. Tatsächlich wurde dies für die eingebauten Singletons, kleine ganze Zahlen und eine Reihe anderer eingebauter Objekte getan.

Wenn Sie die Isolation aufrechterhalten, haben Sie Zugang zu echter Multi-Core-Computing, ohne die Komplikationen, die mit freiem Threading einhergehen. Wenn Sie die Isolation nicht aufrechterhalten, sind Sie den vollen Konsequenzen des freien Threadings ausgesetzt, einschließlich Race Conditions und schwer zu debuggenden Abstürzen.

Davon abgesehen ist eine der größten Herausforderungen bei der Verwendung mehrerer isolierter Interpreter die sichere (ohne Bruch der Isolation) und effiziente Kommunikation zwischen ihnen. Die Laufzeitumgebung und die Standardbibliothek bieten hierfür noch keinen standardisierten Ansatz. Ein zukünftiges Modul der Standardbibliothek würde helfen, den Aufwand für die Aufrechterhaltung der Isolation zu verringern und effektive Werkzeuge für die Kommunikation (und den Austausch) von Daten zwischen Interpretern bereitzustellen.

Hinzugefügt in Version 3.12.

Bugs und Hinweise

Da Sub-Interpreter (und der Haupt-Interpreter) Teil desselben Prozesses sind, ist die Isolierung zwischen ihnen nicht perfekt – zum Beispiel können sie durch die Verwendung von Low-Level-Dateioperationen wie os.close() (versehentlich oder böswillig) die offenen Dateien anderer beeinflussen. Aufgrund der Art und Weise, wie Erweiterungen zwischen (Sub-)Interpretern geteilt werden, funktionieren einige Erweiterungen möglicherweise nicht richtig; dies ist besonders wahrscheinlich bei der Verwendung von Single-Phase-Initialisierung oder (statischen) globalen Variablen. Es ist möglich, Objekte, die in einem Sub-Interpreter erstellt wurden, in den Namensraum eines anderen (Sub-)Interpreters einzufügen; dies sollte nach Möglichkeit vermieden werden.

Besondere Sorgfalt ist geboten, um die gemeinsame Nutzung von benutzerdefinierten Funktionen, Methoden, Instanzen oder Klassen zwischen Sub-Interpretern zu vermeiden, da Importoperationen, die von solchen Objekten ausgeführt werden, den Namensraum des falschen (Sub-)Interpreters beeinflussen können. Es ist ebenso wichtig, Objekte zu vermeiden, von denen die oben genannten erreichbar sind.

Beachten Sie auch, dass die Kombination dieser Funktionalität mit den PyGILState_*-APIs heikel ist, da diese APIs eine Bijektion zwischen Python-Thread-Zuständen und Betriebssystem-Threads annehmen, eine Annahme, die durch die Anwesenheit von Sub-Interpretern gebrochen wird. Es wird dringend empfohlen, keine Sub-Interpreter zwischen einem Paar von übereinstimmenden PyGILState_Ensure() und PyGILState_Release() Aufrufen zu wechseln. Darüber hinaus werden Erweiterungen (wie ctypes), die diese APIs verwenden, um den Aufruf von Python-Code von nicht von Python erstellten Threads zu ermöglichen, wahrscheinlich mit Sub-Interpretern fehlschlagen.

Asynchrone Benachrichtigungen

Es wird ein Mechanismus bereitgestellt, um asynchrone Benachrichtigungen an den Haupt-Interpreter-Thread zu senden. Diese Benachrichtigungen haben die Form eines Funktionszeigers und eines void-Zeiger-Arguments.

int Py_AddPendingCall(int (*func)(void*), void *arg)
Teil der Stable ABI.

Plant die Ausführung einer Funktion im Haupt-Interpreter-Thread. Bei Erfolg wird 0 zurückgegeben und func wird zur Ausführung im Haupt-Thread in die Warteschlange gestellt. Bei einem Fehler wird -1 zurückgegeben, ohne eine Ausnahme zu setzen.

Wenn func erfolgreich in die Warteschlange gestellt wurde, wird es eventuell vom Haupt-Interpreter-Thread mit dem Argument arg aufgerufen. Es wird asynchron zu normal laufendem Python-Code aufgerufen, aber unter Erfüllung beider dieser Bedingungen:

func muss bei Erfolg 0 zurückgeben, oder bei einem Fehler mit gesetzter Ausnahme -1. func wird nicht unterbrochen, um rekursiv eine weitere asynchrone Benachrichtigung durchzuführen, aber es kann dennoch unterbrochen werden, um Threads zu wechseln, wenn der Thread-Zustand abgetrennt wird.

Diese Funktion benötigt keinen angehängten Thread-Zustand. Um diese Funktion jedoch in einem Sub-Interpreter aufzurufen, muss der Aufrufer über einen angehängten Thread-Zustand verfügen. Andernfalls kann die Funktion func dazu geplant werden, vom falschen Interpreter aufgerufen zu werden.

Warnung

Dies ist eine Low-Level-Funktion, die nur in sehr speziellen Fällen nützlich ist. Es gibt keine Garantie, dass func so schnell wie möglich aufgerufen wird. Wenn der Haupt-Thread mit der Ausführung eines Systemaufrufs beschäftigt ist, wird func erst aufgerufen, nachdem der Systemaufruf zurückgekehrt ist. Diese Funktion ist im Allgemeinen **nicht** geeignet, um Python-Code von beliebigen C-Threads aufzurufen. Verwenden Sie stattdessen die PyGILState-API.

Hinzugefügt in Version 3.1.

Geändert in Version 3.9: Wenn diese Funktion in einem Sub-Interpreter aufgerufen wird, wird die Funktion func nun so geplant, dass sie vom Sub-Interpreter aufgerufen wird, anstatt vom Haupt-Interpreter. Jeder Sub-Interpreter hat nun seine eigene Liste geplanter Aufrufe.

Geändert in Version 3.12: Diese Funktion plant nun func immer für die Ausführung im Haupt-Interpreter.

Profiling und Tracing

Der Python-Interpreter bietet eine Low-Level-Unterstützung für die Anbindung von Profiling- und Ausführungs-Tracing-Einrichtungen. Diese werden für Profiling-, Debugging- und Coverage-Analyse-Tools verwendet.

Diese C-Schnittstelle ermöglicht es dem Profiling- oder Tracing-Code, den Overhead des Aufrufs über Python-Level-Callable-Objekte zu vermeiden und stattdessen einen direkten C-Funktionsaufruf zu tätigen. Die wesentlichen Attribute der Einrichtung haben sich nicht geändert; die Schnittstelle erlaubt die Installation von Trace-Funktionen pro Thread, und die grundlegenden Ereignisse, die an die Trace-Funktion gemeldet werden, sind dieselben, die in früheren Versionen an die Python-Level-Trace-Funktionen gemeldet wurden.

typedef int (*Py_tracefunc)(PyObject *obj, PyFrameObject *frame, int what, PyObject *arg)

Der Typ der Trace-Funktion, die mit PyEval_SetProfile() und PyEval_SetTrace() registriert wird. Der erste Parameter ist das Objekt, das der Registrierungsfunktion als obj übergeben wird, frame ist das Frame-Objekt, auf das sich das Ereignis bezieht, what ist eine der Konstanten PyTrace_CALL, PyTrace_EXCEPTION, PyTrace_LINE, PyTrace_RETURN, PyTrace_C_CALL, PyTrace_C_EXCEPTION, PyTrace_C_RETURN oder PyTrace_OPCODE, und arg hängt vom Wert von what ab.

Wert von what

Bedeutung von arg

PyTrace_CALL

Immer Py_None.

PyTrace_EXCEPTION

Ausnahmeinformationen wie von sys.exc_info() zurückgegeben.

PyTrace_LINE

Immer Py_None.

PyTrace_RETURN

Zurückgegebener Wert an den Aufrufer oder NULL, falls durch eine Ausnahme verursacht.

PyTrace_C_CALL

Aufzurufendes Funktions-Objekt.

PyTrace_C_EXCEPTION

Aufzurufendes Funktions-Objekt.

PyTrace_C_RETURN

Aufzurufendes Funktions-Objekt.

PyTrace_OPCODE

Immer Py_None.

int PyTrace_CALL

Der Wert des Parameters what für eine Py_tracefunc Funktion, wenn ein neuer Aufruf einer Funktion oder Methode gemeldet wird oder ein neuer Eintritt in einen Generator. Beachten Sie, dass die Erstellung des Iterators für eine Generatorfunktion nicht gemeldet wird, da kein Kontrolltransfer zum Python-Bytecode im entsprechenden Frame stattfindet.

int PyTrace_EXCEPTION

Der Wert des Parameters what für eine Py_tracefunc Funktion, wenn eine Ausnahme ausgelöst wurde. Die Callback-Funktion wird mit diesem Wert für what aufgerufen, nachdem jeder Bytecode verarbeitet wurde, nach dem die Ausnahme im ausgeführten Frame gesetzt wird. Dies hat zur Folge, dass, wenn die Ausnahmebehandlung den Python-Stack entleert, der Callback bei der Rückkehr zu jedem Frame aufgerufen wird, wenn die Ausnahme propagiert wird. Nur Trace-Funktionen erhalten diese Ereignisse; sie werden vom Profiler nicht benötigt.

int PyTrace_LINE

Der Wert, der als Parameter what an eine Py_tracefunc Funktion (aber nicht an eine Profiling-Funktion) übergeben wird, wenn ein Zeilennummernereignis gemeldet wird. Es kann für einen Frame deaktiviert werden, indem f_trace_lines auf diesem Frame auf 0 gesetzt wird.

int PyTrace_RETURN

Der Wert für den Parameter what für Py_tracefunc Funktionen, wenn ein Aufruf zurückgegeben wird.

int PyTrace_C_CALL

Der Wert für den Parameter what für Py_tracefunc Funktionen, wenn eine C-Funktion aufgerufen wird.

int PyTrace_C_EXCEPTION

Der Wert für den Parameter what für Py_tracefunc Funktionen, wenn eine C-Funktion eine Ausnahme ausgelöst hat.

int PyTrace_C_RETURN

Der Wert für den Parameter what für Py_tracefunc Funktionen, wenn eine C-Funktion zurückgegeben hat.

int PyTrace_OPCODE

Der Wert für den Parameter what für Py_tracefunc Funktionen (aber nicht Profiling-Funktionen), wenn ein neuer Opcode ausgeführt wird. Dieses Ereignis wird standardmäßig nicht ausgelöst: Es muss explizit angefordert werden, indem f_trace_opcodes auf dem Frame auf 1 gesetzt wird.

void PyEval_SetProfile(Py_tracefunc func, PyObject *obj)

Setzt die Profiler-Funktion auf func. Der Parameter obj wird der Funktion als erster Parameter übergeben und kann jedes Python-Objekt sein oder NULL. Wenn die Profiler-Funktion einen Zustand beibehalten muss, bietet die Verwendung eines anderen Wertes für obj für jeden Thread einen bequemen und threadsicheren Ort zur Speicherung. Die Profiler-Funktion wird für alle überwachten Ereignisse aufgerufen, mit Ausnahme von PyTrace_LINE PyTrace_OPCODE und PyTrace_EXCEPTION.

Siehe auch die Funktion sys.setprofile().

Der Aufrufer muss einen Thread-Status angehängt haben.

void PyEval_SetProfileAllThreads(Py_tracefunc func, PyObject *obj)

Wie PyEval_SetProfile(), aber setzt die Profiler-Funktion in allen laufenden Threads des aktuellen Interpreters, anstatt sie nur für den aktuellen Thread zu setzen.

Der Aufrufer muss einen Thread-Status angehängt haben.

Wie PyEval_SetProfile() ignoriert diese Funktion alle Ausnahmen, die beim Setzen der Profiler-Funktionen in allen Threads ausgelöst werden.

Hinzugefügt in Version 3.12.

void PyEval_SetTrace(Py_tracefunc func, PyObject *obj)

Setzt die Tracing-Funktion auf func. Dies ist ähnlich wie PyEval_SetProfile(), mit dem Unterschied, dass die Tracing-Funktion Zeilennummern-Ereignisse und Pro-Opcode-Ereignisse empfängt, aber keine Ereignisse im Zusammenhang mit dem Aufruf von C-Funktionsobjekten erhält. Jede mit PyEval_SetTrace() registrierte Trace-Funktion empfängt nicht PyTrace_C_CALL, PyTrace_C_EXCEPTION oder PyTrace_C_RETURN als Wert für den Parameter what.

Siehe auch die Funktion sys.settrace().

Der Aufrufer muss einen Thread-Status angehängt haben.

void PyEval_SetTraceAllThreads(Py_tracefunc func, PyObject *obj)

Wie PyEval_SetTrace(), aber setzt die Tracing-Funktion in allen laufenden Threads des aktuellen Interpreters, anstatt sie nur für den aktuellen Thread zu setzen.

Der Aufrufer muss einen Thread-Status angehängt haben.

Wie PyEval_SetTrace() ignoriert diese Funktion alle Ausnahmen, die beim Setzen der Trace-Funktionen in allen Threads ausgelöst werden.

Hinzugefügt in Version 3.12.

Referenz-Tracing

Hinzugefügt in Version 3.13.

typedef int (*PyRefTracer)(PyObject*, int event, void *data)

Der Typ der Trace-Funktion, die mit PyRefTracer_SetTracer() registriert wird. Der erste Parameter ist ein Python-Objekt, das gerade erstellt wurde (wenn event auf PyRefTracer_CREATE gesetzt ist) oder zerstört werden soll (wenn event auf PyRefTracer_DESTROY gesetzt ist). Das Argument data ist der undurchsichtige Zeiger, der beim Aufruf von PyRefTracer_SetTracer() angegeben wurde.

Hinzugefügt in Version 3.13.

int PyRefTracer_CREATE

Der Wert für den Parameter event für PyRefTracer Funktionen, wenn ein Python-Objekt erstellt wurde.

int PyRefTracer_DESTROY

Der Wert für den Parameter event für PyRefTracer Funktionen, wenn ein Python-Objekt zerstört wurde.

int PyRefTracer_SetTracer(PyRefTracer tracer, void *data)

Registriert eine Referenz-Tracer-Funktion. Die Funktion wird aufgerufen, wenn ein neues Python-Objekt erstellt wurde oder wenn ein Objekt zerstört wird. Wenn data angegeben ist, muss es ein undurchsichtiger Zeiger sein, der beim Aufruf der Tracer-Funktion bereitgestellt wird. Gibt 0 im Erfolgsfall zurück. Setzt eine Ausnahme und gibt im Fehlerfall -1 zurück.

Beachten Sie, dass Tracer-Funktionen **keine** Python-Objekte intern erstellen dürfen, da der Aufruf sonst reentrant ist. Der Tracer darf auch keine bestehende Ausnahme löschen oder eine Ausnahme setzen. Ein Thread-Zustand ist jedes Mal aktiv, wenn die Tracer-Funktion aufgerufen wird.

Es muss ein angehängter Thread-Zustand vorhanden sein, wenn diese Funktion aufgerufen wird.

Hinzugefügt in Version 3.13.

PyRefTracer PyRefTracer_GetTracer(void **data)

Ruft die registrierte Referenz-Tracer-Funktion und den Wert des undurchsichtigen Datenzeigers ab, der beim Aufruf von PyRefTracer_SetTracer() registriert wurde. Wenn kein Tracer registriert wurde, gibt diese Funktion NULL zurück und setzt den Zeiger data auf NULL.

Es muss ein angehängter Thread-Zustand vorhanden sein, wenn diese Funktion aufgerufen wird.

Hinzugefügt in Version 3.13.

Erweiterte Debugger-Unterstützung

Diese Funktionen sind nur für erweiterte Debugging-Tools bestimmt.

PyInterpreterState *PyInterpreterState_Head()

Gibt das Interpreter-Zustandsobjekt am Anfang der Liste aller solchen Objekte zurück.

PyInterpreterState *PyInterpreterState_Main()

Gibt das Haupt-Interpreter-Zustandsobjekt zurück.

PyInterpreterState *PyInterpreterState_Next(PyInterpreterState *interp)

Gibt das nächste Interpreter-Zustandsobjekt nach interp aus der Liste aller solchen Objekte zurück.

PyThreadState *PyInterpreterState_ThreadHead(PyInterpreterState *interp)

Gibt den Zeiger auf das erste PyThreadState Objekt in der Liste der Threads zurück, die dem Interpreter interp zugeordnet sind.

PyThreadState *PyThreadState_Next(PyThreadState *tstate)

Gibt das nächste Thread-Zustandsobjekt nach tstate aus der Liste aller solchen Objekte zurück, die zum selben PyInterpreterState Objekt gehören.

Unterstützung für Thread-lokalen Speicher

Der Python-Interpreter bietet Low-Level-Unterstützung für Thread-lokalen Speicher (TLS), der die zugrunde liegende native TLS-Implementierung umschließt, um die Python-Level-API für Thread-lokalen Speicher (threading.local) zu unterstützen. Die CPython C-Level-APIs ähneln denen, die von pthreads und Windows angeboten werden: Verwenden Sie einen Thread-Schlüssel und Funktionen, um einen void*-Wert pro Thread zu verknüpfen.

Ein Thread-Zustand muss **nicht** angehängt sein, wenn diese Funktionen aufgerufen werden; sie sorgen selbst für die Sperrung.

Beachten Sie, dass Python.h die Deklaration der TLS-APIs nicht enthält. Sie müssen pythread.h einbinden, um Thread-lokalen Speicher zu verwenden.

Hinweis

Keine dieser API-Funktionen verwaltet den Speicher für die void*-Werte. Sie müssen diese selbst zuweisen und freigeben. Wenn die void*-Werte PyObject* sind, führen diese Funktionen auch keine Referenzzähloperationen darauf aus.

Thread Specific Storage (TSS) API

Die TSS-API wurde eingeführt, um die Verwendung der bestehenden TLS-API im CPython-Interpreter abzulösen. Diese API verwendet einen neuen Typ Py_tss_t anstelle von int zur Darstellung von Thread-Schlüsseln.

Hinzugefügt in Version 3.7.

Siehe auch

„Eine neue C-API für Thread-lokalen Speicher in CPython“ (PEP 539)

type Py_tss_t

Diese Datenstruktur repräsentiert den Zustand eines Thread-Schlüssels, dessen Definition von der zugrunde liegenden TLS-Implementierung abhängen kann, und verfügt über ein internes Feld, das den Initialisierungszustand des Schlüssels darstellt. Diese Struktur hat keine öffentlichen Member.

Wenn Py_LIMITED_API nicht definiert ist, ist die statische Zuweisung dieses Typs durch Py_tss_NEEDS_INIT erlaubt.

Py_tss_NEEDS_INIT

Dieses Makro expandiert zum Initialisierer für Py_tss_t-Variablen. Beachten Sie, dass dieses Makro mit Py_LIMITED_API nicht definiert ist.

Dynamische Zuweisung

Dynamische Zuweisung der Py_tss_t, erforderlich in Erweiterungsmodulen, die mit Py_LIMITED_API erstellt wurden, wo die statische Zuweisung dieses Typs aufgrund seiner undurchsichtigen Implementierung zur Build-Zeit nicht möglich ist.

Py_tss_t *PyThread_tss_alloc()
Teil der Stable ABI seit Version 3.7.

Gibt einen Wert zurück, der denselben Zustand hat wie ein mit Py_tss_NEEDS_INIT initialisierter Wert, oder NULL bei einem Fehler bei der dynamischen Zuweisung.

void PyThread_tss_free(Py_tss_t *key)
Teil der Stable ABI seit Version 3.7.

Gibt den gegebenen, von PyThread_tss_alloc() zugewiesenen key frei, nachdem zuerst PyThread_tss_delete() aufgerufen wurde, um sicherzustellen, dass alle zugeordneten Thread-lokalen Werte zugewiesen wurden. Dies ist ein No-Op, wenn das Argument key NULL ist.

Hinweis

Ein freigegebener Schlüssel wird zu einem hängenden Zeiger. Sie sollten den Schlüssel auf NULL zurücksetzen.

Methoden

Der Parameter key dieser Funktionen darf nicht NULL sein. Darüber hinaus sind die Verhaltensweisen von PyThread_tss_set() und PyThread_tss_get() undefiniert, wenn die gegebene Py_tss_t nicht mit PyThread_tss_create() initialisiert wurde.

int PyThread_tss_is_created(Py_tss_t *key)
Teil der Stable ABI seit Version 3.7.

Gibt einen Wert ungleich Null zurück, wenn die gegebene Py_tss_t von PyThread_tss_create() initialisiert wurde.

int PyThread_tss_create(Py_tss_t *key)
Teil der Stable ABI seit Version 3.7.

Gibt Null im Erfolgsfall bei der Initialisierung eines TSS-Schlüssels zurück. Das Verhalten ist undefiniert, wenn der Wert, auf den das Argument key zeigt, nicht mit Py_tss_NEEDS_INIT initialisiert ist. Diese Funktion kann wiederholt auf demselben Schlüssel aufgerufen werden – ein Aufruf auf einem bereits initialisierten Schlüssel ist ein No-Op und gibt sofort Erfolg zurück.

void PyThread_tss_delete(Py_tss_t *key)
Teil der Stable ABI seit Version 3.7.

Zerstört einen TSS-Schlüssel, um die mit dem Schlüssel in allen Threads verbundenen Werte zu vergessen und den Initialisierungszustand des Schlüssels auf nicht initialisiert zu ändern. Ein zerstörter Schlüssel kann erneut von PyThread_tss_create() initialisiert werden. Diese Funktion kann wiederholt auf demselben Schlüssel aufgerufen werden – ein Aufruf auf einem bereits zerstörten Schlüssel ist ein No-Op.

int PyThread_tss_set(Py_tss_t *key, void *value)
Teil der Stable ABI seit Version 3.7.

Gibt Null zurück, um die erfolgreiche Zuordnung eines void*-Werts zu einem TSS-Schlüssel im aktuellen Thread anzuzeigen. Jeder Thread hat eine separate Zuordnung des Schlüssels zu einem void*-Wert.

void *PyThread_tss_get(Py_tss_t *key)
Teil der Stable ABI seit Version 3.7.

Gibt den void*-Wert zurück, der einem TSS-Schlüssel im aktuellen Thread zugeordnet ist. Gibt NULL zurück, wenn kein Wert dem Schlüssel im aktuellen Thread zugeordnet ist.

Thread Local Storage (TLS) API

Veraltet seit Version 3.7: Diese API wird durch die Thread Specific Storage (TSS) API abgelöst.

Hinweis

Diese Version der API unterstützt keine Plattformen, auf denen der native TLS-Schlüssel so definiert ist, dass er nicht sicher in int umgewandelt werden kann. Auf solchen Plattformen gibt PyThread_create_key() sofort mit einem Fehlerstatus zurück, und die anderen TLS-Funktionen sind auf solchen Plattformen No-Ops.

Aufgrund des oben genannten Kompatibilitätsproblems sollte diese Version der API nicht in neuem Code verwendet werden.

int PyThread_create_key()
Teil der Stable ABI.
void PyThread_delete_key(int key)
Teil der Stable ABI.
int PyThread_set_key_value(int key, void *value)
Teil der Stable ABI.
void *PyThread_get_key_value(int key)
Teil der Stable ABI.
void PyThread_delete_key_value(int key)
Teil der Stable ABI.
void PyThread_ReInitTLS()
Teil der Stable ABI.

Synchronisationsprimitive

Die C-API bietet ein einfaches gegenseitiges Aussperrungs-Lock.

type PyMutex

Ein gegenseitiges Aussperrungs-Lock. PyMutex sollte auf Null initialisiert werden, um den entsperrten Zustand darzustellen. Zum Beispiel

PyMutex mutex = {0};

Instanzen von PyMutex sollten nicht kopiert oder verschoben werden. Sowohl der Inhalt als auch die Adresse eines PyMutex sind bedeutsam und es muss an einer festen, beschreibbaren Stelle im Speicher verbleiben.

Hinweis

Ein PyMutex belegt derzeit ein Byte, aber die Größe sollte als instabil betrachtet werden. Die Größe kann in zukünftigen Python-Versionen ohne eine Abkündigungsperiode geändert werden.

Hinzugefügt in Version 3.13.

void PyMutex_Lock(PyMutex *m)

Sperrt die Mutex m. Wenn ein anderer Thread sie bereits gesperrt hat, wird der aufrufende Thread blockiert, bis die Mutex entsperrt wird. Während der Blockierung wird der Thread den Thread-Zustand vorübergehend trennen, falls einer vorhanden ist.

Hinzugefügt in Version 3.13.

void PyMutex_Unlock(PyMutex *m)

Entsperrt die Mutex m. Die Mutex muss gesperrt sein – andernfalls wird die Funktion einen schwerwiegenden Fehler ausgeben.

Hinzugefügt in Version 3.13.

int PyMutex_IsLocked(PyMutex *m)

Gibt ungleich Null zurück, wenn die Mutex m derzeit gesperrt ist, andernfalls Null.

Hinweis

Diese Funktion ist nur für die Verwendung in Assertions und zur Fehlersuche gedacht und sollte nicht zur Entscheidungsfindung über die Gleichzeitigkeit verwendet werden, da sich der Sperrzustand unmittelbar nach der Überprüfung ändern kann.

Hinzugefügt in Version 3.14.

Python Critical Section API

Die Critical Section API bietet eine Deadlock-Vermeidungsschicht über objektbezogenen Sperren für freigeschaltetes CPython. Sie ist dazu gedacht, die Abhängigkeit vom Global Interpreter Lock zu ersetzen und ist in Python-Versionen mit dem Global Interpreter Lock wirkungslos.

Critical Sections sind für benutzerdefinierte Typen gedacht, die in C-API-Erweiterungen implementiert werden. Sie sollten im Allgemeinen nicht mit integrierten Typen wie list und dict verwendet werden, da ihre öffentlichen C-APIs intern bereits Critical Sections verwenden, mit der bemerkenswerten Ausnahme von PyDict_Next(), für das die Critical Section extern erworben werden muss.

Critical Sections vermeiden Deadlocks, indem sie aktive Critical Sections implizit aussetzen. Daher bieten sie keinen exklusiven Zugriff, wie ihn traditionelle Sperren wie PyMutex bieten. Wenn eine Critical Section gestartet wird, wird die objektbezogene Sperre für das Objekt erworben. Wenn der Code innerhalb der Critical Section C-API-Funktionen aufruft, kann er die Critical Section aussetzen und damit die objektbezogene Sperre freigeben, sodass andere Threads die objektbezogene Sperre für dasselbe Objekt erwerben können.

Varianten, die PyMutex-Zeiger anstelle von Python-Objekten akzeptieren, sind ebenfalls verfügbar. Verwenden Sie diese Varianten, um eine Critical Section in einer Situation zu starten, in der kein PyObject vorhanden ist – zum Beispiel, wenn Sie mit einem C-Typ arbeiten, der PyObject nicht erweitert oder umschließt, aber trotzdem in die C-API auf eine Weise aufrufen müssen, die zu Deadlocks führen könnte.

Die von den Makros verwendeten Funktionen und Strukturen werden für Fälle offengelegt, in denen C-Makros nicht verfügbar sind. Sie sollten nur wie in den gegebenen Makroerweiterungen verwendet werden. Beachten Sie, dass sich die Größen und Inhalte der Strukturen in zukünftigen Python-Versionen ändern können.

Hinweis

Operationen, die zwei Objekte gleichzeitig sperren müssen, müssen Py_BEGIN_CRITICAL_SECTION2 verwenden. Sie dürfen keine verschachtelten Critical Sections verwenden, um mehr als ein Objekt gleichzeitig zu sperren, da die innere Critical Section die äußeren Critical Sections aussetzen kann. Diese API bietet keine Möglichkeit, mehr als zwei Objekte gleichzeitig zu sperren.

Beispielverwendung

static PyObject *
set_field(MyObject *self, PyObject *value)
{
   Py_BEGIN_CRITICAL_SECTION(self);
   Py_SETREF(self->field, Py_XNewRef(value));
   Py_END_CRITICAL_SECTION();
   Py_RETURN_NONE;
}

Im obigen Beispiel ruft Py_SETREF Py_DECREF auf, was durch die Deallokationsfunktion eines Objekts beliebigen Code aufrufen kann. Die Critical Section API vermeidet potenzielle Deadlocks aufgrund von Reentrancy und Sperrreihenfolgen, indem sie es der Laufzeitumgebung ermöglicht, die Critical Section vorübergehend auszusetzen, wenn der durch den Finalizer ausgelöste Code blockiert und PyEval_SaveThread() aufruft.

Py_BEGIN_CRITICAL_SECTION(op)

Erlangt die objektbezogene Sperre für das Objekt op und beginnt eine Critical Section.

Im freigeschalteten Build expandiert dieses Makro zu

{
    PyCriticalSection _py_cs;
    PyCriticalSection_Begin(&_py_cs, (PyObject*)(op))

Im Standard-Build expandiert dieses Makro zu {.

Hinzugefügt in Version 3.13.

Py_BEGIN_CRITICAL_SECTION_MUTEX(m)

Sperrt die Mutex m und beginnt eine Critical Section.

Im freigeschalteten Build expandiert dieses Makro zu

{
     PyCriticalSection _py_cs;
     PyCriticalSection_BeginMutex(&_py_cs, m)

Beachten Sie, dass im Gegensatz zu Py_BEGIN_CRITICAL_SECTION keine Typumwandlung für das Argument des Makros erfolgt – es muss ein PyMutex-Zeiger sein.

Im Standard-Build expandiert dieses Makro zu {.

Hinzugefügt in Version 3.14.

Py_END_CRITICAL_SECTION()

Beendet die Critical Section und gibt die objektbezogene Sperre frei.

Im freigeschalteten Build expandiert dieses Makro zu

    PyCriticalSection_End(&_py_cs);
}

Im Standard-Build expandiert dieses Makro zu }.

Hinzugefügt in Version 3.13.

Py_BEGIN_CRITICAL_SECTION2(a, b)

Erlangt die objektbezogenen Sperren für die Objekte a und b und beginnt eine Critical Section. Die Sperren werden in konsistenter Reihenfolge (niedrigste Adresse zuerst) erlangt, um Deadlocks bei der Sperrreihenfolge zu vermeiden.

Im freigeschalteten Build expandiert dieses Makro zu

{
    PyCriticalSection2 _py_cs2;
    PyCriticalSection2_Begin(&_py_cs2, (PyObject*)(a), (PyObject*)(b))

Im Standard-Build expandiert dieses Makro zu {.

Hinzugefügt in Version 3.13.

Py_BEGIN_CRITICAL_SECTION2_MUTEX(m1, m2)

Sperrt die Mutexen m1 und m2 und beginnt eine Critical Section.

Im freigeschalteten Build expandiert dieses Makro zu

{
     PyCriticalSection2 _py_cs2;
     PyCriticalSection2_BeginMutex(&_py_cs2, m1, m2)

Beachten Sie, dass im Gegensatz zu Py_BEGIN_CRITICAL_SECTION2 keine Typumwandlung für die Argumente des Makros erfolgt – es müssen PyMutex-Zeiger sein.

Im Standard-Build expandiert dieses Makro zu {.

Hinzugefügt in Version 3.14.

Py_END_CRITICAL_SECTION2()

Beendet die Critical Section und gibt die objektbezogenen Sperren frei.

Im freigeschalteten Build expandiert dieses Makro zu

    PyCriticalSection2_End(&_py_cs2);
}

Im Standard-Build expandiert dieses Makro zu }.

Hinzugefügt in Version 3.13.