J'introduis l'interpréteur Python dans un programme C. Cependant, il peut arriver que l'exécution de certains scripts python via PyRun_SimpleString()
se déroule en boucle infinie ou s'exécute trop longtemps. Envisager PyRun_SimpleString("while 1: pass");
En empêchant le programme principal de bloquer j'ai pensé que je pourrais exécuter l'interprète dans un fil. Comment arrêter l'exécution du script python dans l'interpréteur intégré s'exécutant dans un thread sans arrêter le processus entier?Arrêt de Python incorporé
Est-il possible de transmettre une exception à l'interpréteur? Dois-je envelopper le script sous un autre script qui écouterait les signaux?
PS: Je pourrais courir le python dans un processus distinct, mais ce n'est pas ce que je veux - à moins que ce soit le dernier recours ...
Mise à jour:
Ainsi, il fonctionne maintenant. Merci Denis Otkidach, encore une fois!
Si je vois bien, vous devez faire deux choses: dites à l'interpréteur d'arrêter et return -1
dans le même thread que votre PyRun_SimpleString() est en cours d'exécution. Pour stopper, on a quelques possibilités: PyErr_SetString(PyExc_KeyboardInterrupt, "...")
ou PyErr_SetInterrupt()
- le premier peut laisser Python exécuter quelques instructions de plus puis il s'arrête, le dernier stoppe immédiatement l'exécution.
Pour return -1
, vous utilisez Py_AddPendingCall()
pour injecter un appel de fonction dans l'exécution Python. Les docs le mentionnent depuis la version 2.7 et 3.1 mais il fonctionne aussi sur les versions antérieures de Python (2.6 ici). De 2.7 et 3.1 il devrait aussi être thread-safe, ce qui signifie que vous pouvez l'appeler sans acquérir GIL (?).
Donc, on pourrait réécrire l'exemple ci-dessous:
int quit() {
PyErr_SetInterrupt();
return -1;
}
Ce look * très intéressant mais n'est-ce pas le tout nouveau Python? (2.7 alpha est sorti juste aujourd'hui.) Cependant, je pourrais passer à Python 3.1 - mais quoi alors? Quelle fonction devrais-je enregistrer via 'Py_AddPendingCall()'? 'PyErr_SetString()'? 'Py_Exit()'? 'Py_Finalize()'? –
Py_AddPendingCall existe au moins à partir de python 2.0 (défini dans ceval.h).J'ai ajouté un exemple de code à ma réponse. –
Merci! Ça marche! –