2010-01-29 7 views
4

Dans mon programme, j'ai un tas de threads en cours d'exécution et j'essaie d'interrompre le thread principal pour l'amener à faire quelque chose de manière asynchrone. Je mis en place un gestionnaire et envoyer le processus principal un SIGUSR1 - voir le code ci-dessous:Traitement du signal en Python

def SigUSR1Handler(signum, frame): 

    self._logger.debug('Received SIGUSR1') 

    return 

signal.signal(signal.SIGUSR1, SigUSR1Handler) 

[signal.signal(signal.SIGUSR1, signal.SIG_IGN)] 

Dans le cas ci-dessus, tous les fils et les principaux arrêts processus - point d'un « c » de voir ceci était inattendu - je veux que les discussions continuent comme elles étaient étaient avant le signal. Si je mets le SIG_IGN à la place, tout continue bien.

Quelqu'un peut-il me dire comment faire? Peut-être que je dois faire quelque chose avec le « cadre » manuellement pour revenir là où il was..just une supposition bien merci à l'avance,


Merci pour votre aide à ce sujet.

Pour expliquer un peu plus, j'ai des instances de thread écrivant des informations de chaîne à une socket qui est également sortie dans un fichier. Ces threads exécutent leurs propres temporisateurs de sorte qu'ils écrivent indépendamment leurs sorties sur le socket. Lorsque le programme s'exécute, je vois aussi leur sortie sur stdout mais tout s'arrête dès que je vois la ligne de débogage du signal.

J'ai besoin des threads pour envoyer constamment ces informations mais j'ai besoin que le programme principal prenne une commande pour qu'il commence aussi à faire quelque chose d'autre (en parallèle) pendant un moment. Je pensais pouvoir envoyer un signal depuis la ligne de commande pour déclencher cela.

+1

* "tous les filets et le processus principal s'arrête" * Voulez-vous dire que le processus est tué? Est-ce que ça plante? –

+0

en suivant les étapes ci-dessus dans un programme mono-thread, puis 'killall -USR1 python' a fonctionné, btw. – PypeBros

Répondre

2

Le mélange de signaux et de filetages est toujours un peu précaire. Ce que vous décrivez ne devrait pas arriver, cependant. Python ne gère que les signaux dans le thread principal. Si le système d'exploitation envoie le signal à un autre thread, ce thread peut être brièvement interrompu (lorsqu'il exécute, par exemple, un appel système) mais il n'exécutera pas le gestionnaire de signal. Le thread principal sera invité à exécuter le gestionnaire de signaux à la prochaine opportunité.

Que font vos threads (y compris le thread principal) lorsque vous envoyez le signal? Comment remarquez-vous qu'ils s'arrêtent tous? Est-ce une courte pause (facilement expliquée par le fait que le thread principal devra acquérir le GIL avant de manipuler le signal) ou le processus est-il complètement interrompu?

0

Vous devriez probablement utiliser une variable threading.Condition au lieu d'envoyer des signaux. Demandez à votre thread principal de vérifier chaque boucle et d'effectuer son opération spéciale si elle a été définie.

Si vous insistez sur l'utilisation de signaux, vous voudrez passer à l'utilisation de sous-processus au lieu de threads, car votre problème est probablement dû au GIL.

1

Je vais répondre tri de ma propre question: Dans ma première tentative de ce que j'utilisais time.sleep (run_time) dans le thread principal pour contrôler combien de temps les fils ont couru jusqu'à ce qu'ils soient arrêtés. En ajoutant debug je pouvais voir que la boucle de sommeil semblait se fermer dès que le gestionnaire de signal est revenu, donc tout s'arrêtait normalement mais tôt!

J'ai remplacé la veille par une boucle while et cela ne saute pas après que le gestionnaire de signal retourne pour que mes threads continuent à fonctionner.Donc, il résout le problème mais je suis encore un peu perplexe sur le comportement de sleep().

0

Regardez cette présentation par David Beazley.

http://blip.tv/file/2232410

Il explique également un comportement excentrique liés aux threads et les signaux (Python spécifique, et non la bizarrerie générale du sujet :-)). Pyprocessing est une bibliothèque soignée qui facilite le travail avec des processus séparés en Python.

+0

présentation a été retiré de blip. Avez-vous un titre, etc afin que nous puissions trouver une autre copie? – spazm

+1

@spazm, un peu de googling pour "david beazley signal de manipulation python" avéré http://www.pyvideo.org/video/353/pycon-2010--understanding-the-python-gil---82. Je ne fais plus beaucoup de Python, mais je parie que le reste des vidéos de David Beazley valent aussi une montre ou deux. S'amuser! [modifier: grammaire] –