OVH Cloud OVH Cloud

Eviter les threads infinis

4 réponses
Avatar
Python-Fr
Bonjour,
je d=E9veloppe un serveur HTTP multithreads, qui permet aux utilisateurs
d'int=E9grer du code Python (ex=E9cut=E9 en environnement restreint sans
builtins) dans ses messages. Tout marche tr=E8s bien mais j'ai peur
qu'un utilisateur mal intentionn=E9 cr=E9e une boucle infinie, qui bloque
le thread, ralentisse le serveur et emp=EAche la suite de la
g=E9n=E9ration de la page et donc d'y acc=E9der.

J'aimerais donc savoir comment tuer un tel thread ( apr=E8s un certin
temps, par exemple ). J'ai lu que tuer les threads en Python ne
semblait pas si facile que =E7a... Faudrait-il alors emp=EAcher l'usage
de "while" et "for" dans le code ? Cette solution ne me plait pas
beaucoup mais si c'est la seule envisageable...

Au fait, quelqu'un sait-il comment fait Zope, par exemple ?

4 réponses

Avatar
Encolpe Degoute
Bonjour,
je développe un serveur HTTP multithreads, qui permet aux utilisateurs
d'intégrer du code Python (exécuté en environnement restreint sans
builtins) dans ses messages. Tout marche très bien mais j'ai peur
qu'un utilisateur mal intentionné crée une boucle infinie, qui bloque
le thread, ralentisse le serveur et empêche la suite de la
génération de la page et donc d'y accéder.

J'aimerais donc savoir comment tuer un tel thread ( après un certin
temps, par exemple ). J'ai lu que tuer les threads en Python ne
semblait pas si facile que ça... Faudrait-il alors empêcher l'usage
de "while" et "for" dans le code ? Cette solution ne me plait pas
beaucoup mais si c'est la seule envisageable...

Au fait, quelqu'un sait-il comment fait Zope, par exemple ?


Oui: il boucle et prends toutes les ressources disponibles.
Par contre il est possible de tuer les threads au bout d'un certain
temps. C'est utilisé dans PloneXeFile/AttachmentField pour tuer des
processus externes de conversions de fichiers bureautiques.

--
Encolpe DEGOUTE
http://encolpe.degoute.free.fr/
Logiciels libres, hockey sur glace et autres activités cérébrales

Avatar
Laurent Pointal
Encolpe Degoute wrote:

Bonjour,
je développe un serveur HTTP multithreads, qui permet aux utilisateurs
d'intégrer du code Python (exécuté en environnement restreint sans
builtins) dans ses messages. Tout marche très bien mais j'ai peur
qu'un utilisateur mal intentionné crée une boucle infinie, qui bloque
le thread, ralentisse le serveur et empêche la suite de la
génération de la page et donc d'y accéder.

J'aimerais donc savoir comment tuer un tel thread ( après un certin
temps, par exemple ). J'ai lu que tuer les threads en Python ne
semblait pas si facile que ça... Faudrait-il alors empêcher l'usage
de "while" et "for" dans le code ? Cette solution ne me plait pas
beaucoup mais si c'est la seule envisageable...

Au fait, quelqu'un sait-il comment fait Zope, par exemple ?



Oui: il boucle et prends toutes les ressources disponibles.
Par contre il est possible de tuer les threads au bout d'un certain
temps. C'est utilisé dans PloneXeFile/AttachmentField pour tuer des
processus externes de conversions de fichiers bureautiques.



Thread/Process c'est pas la même chose...

"aucun problème" pour les process - l'OS libère les ressources.

Pour un thread... pas moyen de faire propre (il partage ses ressources
avec les autres threads qui eux peuvent continuer à en avoir besoin...
peut-être). Et en plus, avec Python, une partie des ressources sont les
objets avec leurs compteurs de références, qu'il faudrais mettre à jour.

Pour pouvoir stopper définitivement un thread type démon... il faut
l'écrire avec une condition de sortie propre (évènement ou variable à
positionner...).

while not must_exit :
....


A+

Laurent.


Avatar
Python-Fr
L'idéal serait-il donc de lancer en parallèle un "serveur
d'exécution de code", multithreadé, en Python ? Il ne faudrait pas
lancer un interpréteur Python au moment de la requête et si
l'exécution du code "sensible" n'est pas terminée après un certain
temps, de "tuer" et relancer le serveur ?
Avatar
Laurent Pointal
Python-Fr wrote:

L'idéal serait-il donc de lancer en parallèle un "serveur
d'exécution de code", multithreadé, en Python ? Il ne faudrait pas
lancer un interpréteur Python au moment de la requête et si
l'exécution du code "sensible" n'est pas terminée après un certain
temps, de "tuer" et relancer le serveur ?


[désolé pour le retard à la réponse]

En effet, si tu veux "tuer" un thread, il faut que tu en fasses un processus
séparé. Si le temps de traitement est long, ça peut valoir le coup (reste
le problème du passage d'arguments & Co, très dépendant de ce que tu as
besoin). Si le temps de traitement est plutôt court, voir peut-être à avoir
un process séparé qui effectue les traitements les uns à la suite des
autres... et si un traitement dure trop longtemps, tu peux tuer le process
et le relancer - bref un daemon.

Si tu mets une jolie mécanique en place, ça pourait en intéresser d'autres.

QQ Pistes. Pour les passages de paramètres, ça peut bien sûr se faire via
les paramètres de la ligne de commande (le plus simple), mais il y a aussi
la possibilité du fichier partagé, de la mémoire partagée, des appels
distants via Pyro (Python Remote Object - un genre de RMI pour Python)...

A+

Laurent.