Ich bin Python-Interpreter in ein C-Programm einbetten. Es kann jedoch vorkommen, dass beim Ausführen eines Python-Skripts über PyRun_SimpleString()
eine Endlosschleife ausgeführt wird oder zu lange ausgeführt wird. Betrachten Sie PyRun_SimpleString("while 1: pass");
In der Verhinderung der Blockierung des Hauptprogramms dachte ich, ich könnte den Interpreter in einem Thread ausführen.Eingebettete Python stoppen
Wie höre ich auf, das Python-Skript in eingebetteten Interpreter auszuführen, der in einem Thread ausgeführt wird, ohne den gesamten Prozess zu beenden?
Kann eine Ausnahme an den Interpreter übergeben werden? Sollte ich das Skript unter ein anderes Skript schreiben, das auf Signale hört?
PS: Ich konnte die Python in einem separaten Prozess ausgeführt, aber das ist nicht das, was ich will - es sei denn, es der letzte Ausweg ist ...
Update:
es also, funktioniert jetzt. Danke, Denis Otkidach, noch einmal!
Wenn ich das richtig sehe, haben Sie zwei Dinge zu tun: den Dolmetscher sagen, und return -1
im selben Thread wie Ihre PyRun_SimpleString stop() ausgeführt wird.
Um zu stoppen, hat man ein paar Möglichkeiten: PyErr_SetString(PyExc_KeyboardInterrupt, "...")
oder PyErr_SetInterrupt()
- die erste könnte Python noch ein paar Anweisungen laufen lassen und dann stoppt es, die spätere stoppt die Ausführung sofort.
Um return -1
verwenden Sie Py_AddPendingCall()
, um einen Funktionsaufruf in Python-Ausführung zu injizieren. Die Dokumente erwähnen es seit Version 2.7 und 3.1, aber es läuft auch auf früheren Pythons (2.6 hier). Ab 2.7 und 3.1 sollte es auch threadsicher sein, dh Sie können es aufrufen, ohne GIL (?) Zu erwerben.
So könnte man das Beispiel umschreiben Gebrüll:
int quit() {
PyErr_SetInterrupt();
return -1;
}
Dieser Look * sehr * interessant, aber ist es nicht für die neueste Python? (2.7 alpha stieg gerade heute aus.) Allerdings könnte ich auf Python 3.1 upgraden - aber was dann? Welche Funktion soll ich über 'Py_AddPendingCall()' registrieren? 'PyErr_SetString()'? 'Py_Exit()'? 'Py_Finalize()'? –
Py_AddPendingCall existiert mindestens von Python 2.0 (definiert in ceval.h).Ich habe meiner Antwort einen Beispielcode hinzugefügt. –
Danke! Es klappt! –