9
votes

Python: Django: Handler signal et fil principal

Je construis une application Django qui dépend d'un module Python où un gestionnaire de signal Sigint a été mis en œuvre.

En supposant que je ne puisse pas changer le module que je dépend de, comment puis-je contourner le «signal fonctionne uniquement dans le fil principal» que je reçois l'intégrant dans Django?

Puis-je l'exécuter sur le fil principal de Django? Existe-t-il un moyen d'inhiber le gestionnaire pour permettre au module de fonctionner sur des threads non principaux?

Merci!


1 commentaires

J'ai le même problème. La partie étrange est que je suis à peu près sûr que je n'utilise aucun discussion. Je suis juste en cours d'exécution gérer.py runserver.


4 Réponses :


0
votes

Bien que la question ne décrit pas exactement la situation dans laquelle vous vous trouvez, voici quelques conseils génériques:

Le signal est envoyé uniquement au fil principal. Pour cette raison, le gestionnaire de signal doit être dans le fil principal. À partir de ce point, l'action que le déclencheur du signal doit être communiquée aux autres threads. Je fais habituellement cela en utilisant événements . Le gestionnaire de signal définit l'événement que les autres threads liront, puis réalisez que l'action X a été déclenchée. Évidemment, cela implique que l'attribut d'événement doit être partagé entre les threads.


0 commentaires

6
votes

Le serveur de développement intégré de Django a une fonctionnalité de rechargement automatique activée par défaut qui espionne un nouveau thread en tant que moyen de rechargement de code. Pour contourner ce problème, vous pouvez simplement faire ce qui suit, bien que vous perdiez évidemment la commodité de la rechargement automatique:

python manage.py runserver --noreload


0 commentaires

3
votes

J'utilise Python 3.5 et Django 1.8.5 avec mon projet et j'ai récemment rencontré un problème similaire. Je peux facilement exécuter mon code xxx.py avec Signal directement, mais il ne peut pas être exécuté sur Django en tant que package juste à cause de l'erreur " SIGNAL UNIQUEMENT Fonctionne dans le fil principal ".

Premièrement, RunServer avec - NORLELOAD --NOTHREADING est utilisable mais il exécute mon code multi-thread trop lent pour moi.

Deuxièmement, j'ai trouvé ce code dans __ init __. py de mon colis a couru dans le fil principal. Mais, bien sûr, seul le thread principal peut attraper ce signal Signal , mon code dans le paquet ne peut pas l'attraper du tout. Cela ne peut pas résoudre mon problème, bien que cela puisse être une solution pour vous.

Enfin, j'ai trouvé qu'il existe un module intégré nommé sous-processus en python. Cela signifie que vous pouvez exécuter un processus complet sous réel avec celui-ci, c'est-à-dire que ce processus a son propre thread principal. Vous pouvez donc exécuter votre code avec Signal facilement ici. Bien que je ne connaisse pas la performance avec l'utilisation, cela fonctionne bien pour moi. PS, vous pouvez trouver tous les détails sur Subprocess dans la documentation Python.

merci ~


0 commentaires

2
votes

Il existe une manière plus propre, qui ne casse pas votre capacité à utiliser des threads et des processus.

Mettez vos appels d'inscription dans Manage.py: P>

def handleKill(signum, frame):
    print "Killing Thread."
    # Or whatever code you want here
    ForceTerminate.FORCE_TERMINATE = True 
    print threading.active_count()
    exit(0)


if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mysite.settings")

from django.core.management import execute_from_command_line

signal.signal(signal.SIGINT, handleKill)
signal.signal(signal.SIGTERM, handleKill)

execute_from_command_line(sys.argv)


0 commentaires