2016-03-06 1 views
0

Je veux démarrer une nouvelle instance de mon script python quand il atteint une heure spécifiée pendant l'heure et tuer l'instance en cours. Le script python démarre automatiquement avec le démarrage à l'aide d'un crontab. Une boucle while infinie lit les données. S'il y a des données entrantes entre les minutes 59 secondes 30 et 59 secondes 59 secondes, le fichier se ferme et je veux que le script démarre une nouvelle instance de lui-même avec un nouvel identifiant de processus et tue l'ancien processus. En ce moment je fais cela en utilisantScript python à tuer et se lancer

subprocess.call(['python', '/home/pi/script.py']) 
    sys.exit(1) 

Cela démarre une nouvelle instance du script python, mais l'ancien est toujours visible et (il semble) actif quand je vérifie les processus avec top.

Y a-t-il une meilleure façon de laisser le programme démarrer et se tuer dans le script python?

Une autre approche à l'aide d'un script bash appelé par le script python:

#!/bin/sh 

PID=`ps -eaf | grep python | grep -v grep | awk '{print $2}'` 
if [[ "" != "$PID" ]]; then 
    echo "killing $PID" 
    kill -9 $PID 
    sleep 1 
    sudo python /home/pi/readserial_V4_RP.py & 
    exit 1 
fi 

Mais cela ne peut pas fonctionner parce que la fin du script python, avant que le script bash peut tuer. Je pourrais démarrer le script python sans tuer les processus python , mais comment puis-je être sûr qu'aucun script python n'est en cours d'exécution avant de démarrer la nouvelle instance du script python.

parce que j'ai le sentiment, quand j'ai plus d'un même scripts python en cours d'exécution, que le premier qui a débuté fait tout le « travail » et les autres sont juste au ralenti ...

Répondre

0

A mieux serait d'utiliser:

child = subprocess.Popen(['python','/home/pi/script.py'],shell=True,stdout=subprocess.PIPE) 
    output,error = child.communicate() 
    print output, error 
    sys.exit() 
+0

Thx! Je l'ai essayé avec 'shell = True' aussi, mais avec le même résultat. Je suppose que le stdout me donne un journal où je peux voir des erreurs s'il y en a? Ou que fait-il? – BallerNacken

+0

La fonction de communication() ne retourne pas jusqu'à ce que le processus se termine. Si vous souhaitez contrôler le processus, utilisez poll() et vérifiez régulièrement le contenu de la sortie. Quand il est temps de tuer le processus, le script externe peut utiliser kill(). – Neil

+0

@Henin RK Votre approche ne semble pas fonctionner. Le processus en cours se termine, mais le script ne redémarre pas. Est-il vrai, que de la façon dont je le fais pour le moment, l'ancienne instance du script python est le processus parent et l'enfant ne peut être tué que si le parent se termine? J'ai édité un script bash dans ma question avec une approche différente et un problème. – BallerNacken

0

au lieu d'avoir un processus d'essayer de se remettre en marche, un script mince parent qui exécute le script réel. Le moniteur parent redémarre le script à chaque fermeture. Puisque le parent attend jusqu'à ce que l'enfant ait complètement quitté, vous n'aurez pas plusieurs versions en cours d'exécution. Dans une implémentation complète, le parent contient le code du démon système dont vous avez besoin et l'enfant est concentré sur la tâche.

Cet exemple exécute un programme très ennuyeux qui dort pour le nombre de secondes spécifié sur la ligne de commande

import multiprocessing 
import time 
import sys 
import os 
import traceback 

def the_real_work_done_here(sleep_time): 
    try: 
     print(os.getpid(), 'start work') 
     time.sleep(sleep_time) 
     print(os.getpid(), 'end work') 
     exit(0) 
    except Exception: 
     traceback.print_exc() 
     exit(2) 

def monitor(sleep_time): 
    while 1: 
     proc = multiprocessing.Process(target=the_real_work_done_here, 
      args=(sleep_time,)) 
     proc.start() 
     proc.join() 
     if proc.exitcode != 0: 
      print('something went wrong... terminating') 
      exit(proc.exitcode) 


if __name__ == '__main__': 
    try: 
     sleep_time = int(sys.argv[1]) 
     monitor(sleep_time) 
    except (KeyError, ValueError): 
     print('usage: test.py sleeptime') 
     exit(1) 
+0

Cela semble vraiment utile. Je vais essayer demain et donner une réponse. Thx jusqu'ici les gars! – BallerNacken