129 votes

Vérifiez si le script python est en cours d'exécution

J'ai un python démon s'exécute comme une partie de mon application web/ Comment puis-je vérifier rapidement (à l'aide de python) si mon démon est en cours d'exécution et, si non, le lancer?

Je veux le faire de cette façon de réparer les accidents du démon, et donc le script ne doit pas être exécuté manuellement, il s'exécute automatiquement dès qu'il est appelé, et puis rester en cours d'exécution.

Comment puis-je vérifier (à l'aide de python) si mon script est en cours d'exécution?

176voto

aychedee Points 7352

Une technique qui est à portée de main sur un système Linux est à l'aide de sockets de domaine:

import socket
import sys
import time

def get_lock(process_name):
    global lock_socket
    lock_socket = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
    try:
        lock_socket.bind('\0' + process_name)
        print 'I got the lock'
    except socket.error:
        print 'lock exists'
        sys.exit()


get_lock('running_test')
while True:
    time.sleep(3)

Il est atomique et évite le problème de verrouillage de fichiers qui traînent si votre processus est envoyé un signal SIGKILL

109voto

Dan Udey Points 1994

Déposez un pidfile quelque part (par exemple, /tmp). Ensuite, vous pouvez vérifier pour voir si le processus est en cours d'exécution par la vérification pour voir si le PID dans le fichier existe. Ne pas oublier de supprimer le fichier lorsque vous arrêter proprement, et de les vérifier quand vous démarrez.

#/usr/bin/env python

import os
import sys

pid = str(os.getpid())
pidfile = "/tmp/mydaemon.pid"

if os.path.isfile(pidfile):
    print "%s already exists, exiting" % pidfile
    sys.exit()
else:
    file(pidfile, 'w').write(pid)

# Do some actual work here

os.unlink(pidfile)

Ensuite, vous pouvez vérifier pour voir si le processus est en cours d'exécution par la vérification pour voir si le contenu de /tmp/mydaemon.pid sont un processus existant. Monit (mentionné ci-dessus) peut faire pour vous, ou vous pouvez écrire un simple script shell case pour vous, en utilisant le code de retour du ps.

ps up `cat /tmp/mydaemon.pid ` >/dev/null && echo "Running" || echo "Not running"

Pour le crédit supplémentaire, vous pouvez utiliser le atexit module pour vous assurer que votre programme nettoie ses pidfile en toutes circonstances (quand ils sont tués, les exceptions soulevées, etc.).

11voto

Shylock Points 91

Bien sûr, l'exemple de Dan ne fonctionnera pas comme il se doit.

En effet, si le script crash, lever une exception, ou ne pas nettoyer le fichier pid, le script sera exécuté plusieurs fois.

Je suggère ce qui suit à partir d'un autre site web:

C'est pour vérifier s'il existe déjà un fichier de verrouillage existant

\#/usr/bin/env python
import os
import sys
if os.access(os.path.expanduser("~/.lockfile.vestibular.lock"), os.F_OK):
        #if the lockfile is already there then check the PID number
        #in the lock file
        pidfile = open(os.path.expanduser("~/.lockfile.vestibular.lock"), "r")
        pidfile.seek(0)
        old_pid = pidfile.readline()
        # Now we check the PID from lock file matches to the current
        # process PID
        if os.path.exists("/proc/%s" % old_pid):
                print "You already have an instance of the program running"
                print "It is running as process %s," % old_pid
                sys.exit(1)
        else:
                print "File is there but the program is not running"
                print "Removing lock file for the: %s as it can be there because of the program last time it was run" % old_pid
                os.remove(os.path.expanduser("~/.lockfile.vestibular.lock"))

C'est la partie du code où nous avons mis un fichier PID dans le fichier de verrouillage

pidfile = open(os.path.expanduser("~/.lockfile.vestibular.lock"), "w")
pidfile.write("%s" % os.getpid())
pidfile.close()

Ce code permet de vérifier la valeur de pid par rapport aux processus en cours d'exécution., éviter la double exécution.

J'espère que ça aidera.

9voto

ojblass Points 7423

Il existe de très bons packages pour des processus de redémarrage sur UNIX. Celui qui a un bon tutoriel sur la création et la configuration, il est monit. Avec quelques réglages, vous pouvez avoir un roc solide de la technologie éprouvée de maintenir vos démon.

2voto

debuti Points 95

Essayez cette autre version

def checkPidRunning(pid):        
    '''Check For the existence of a unix pid.
    '''
    try:
        os.kill(pid, 0)
    except OSError:
        return False
    else:
        return True

# Entry point
if __name__ == '__main__':
    pid = str(os.getpid())
    pidfile = os.path.join("/", "tmp", __program__+".pid")

    if os.path.isfile(pidfile) and checkPidRunning(int(file(pidfile,'r').readlines()[0])):
            print "%s already exists, exiting" % pidfile
            sys.exit()
    else:
        file(pidfile, 'w').write(pid)

    # Do some actual work here
    main()

    os.unlink(pidfile)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X