Exécute un seul script Perl instance par cron
J'ai besoin d'exécuter le script Perl par cron périodiquement (~tous les 3 à 5 minutes). Je tiens à vous assurer que seul un script Perl instance va être en cours d'exécution dans le temps, de sorte prochain cycle ne démarre pas jusqu'à ce que la précédente est terminée. Pourrait/Devrait être atteint par certaines fonctionnalités intégrées de cron, Perl ou j'ai besoin de le gérer au niveau de script?
Je suis tout à fait nouveau pour Perl et cron, afin d'aider et de recommandations d'ordre général sont appréciés.
- La plate-forme parlez-vous? *nix?
- Ça va fonctionner sur linux
- blog.booking.com/highlander-daemons-without-daemons.html
Vous devez vous connecter pour publier un commentaire.
J'ai toujours eu de la chance de l'aide Fichier::NFSLock pour obtenir un verrou exclusif sur le script lui-même.
C'est en quelque sorte le même que l'autre fichier de verrouillage des suggestions, sauf que je n'ai pas à faire autre chose que de tenter d'obtenir la serrure.
exit 0 unless $lock;
Utilisation Fichier::Pid pour stocker le pid du script dans un fichier, le script doit vérifier au début, l'abandon et s'il est trouvé. Vous pouvez supprimer le pidfile quand le script est fait, mais ce n'est pas vraiment nécessaire, comme vous pouvez simplement vérifier plus tard pour voir si l'id de processus est encore en vie (ce qui prendra en compte également le cas lorsque le script s'interrompt de façon inattendue):
La Sys::RunAlone module fait ce que vous voulez très bien. Juste ajouter
près du haut de votre code.
Une approche classique consiste pour chaque processus d'ouverture et de fermeture d'un certain fichier. Ensuite, le processus lit l'ID de processus contenues dans le fichier.
Si un processus d'identification est en cours d'exécution, le retardataire sort tranquillement. Sinon, le nouveau gagnant écrit son numéro de processus (
$$
en Perl) pour le pidfile, ferme la poignée (qui libère le verrou), et vaque à ses affaires.Exemple de mise en œuvre ci-dessous:
Autant que je sache, perl n'a pas une telle chose bâtiment. Vous pouvez facilement créer des fichiers temporaires, lorsque vous démarrez votre application et de le supprimer, lorsque le script est terminé.
J'ai toujours utilisé ce - petit et simple - pas de dépendance sur n'importe quel module et fonctionne à la fois sur Windows + Linux.
Compte tenu de la fréquence normalement j'écris un démon (serveur) qui joliment attend les bras croisés entre l'exécution du travail (c'est à dire
sleep()
) plutôt que d'essayer d'utiliser cron pour assez fine des accès.Si nécessaire, sur les systèmes Unix /Linux vous pouvez exécuter à partir de
/etc/inittab
(ou de remplacement) pour s'assurer qu'il est toujours en cours d'exécution, et est automatiquement redémarré dans le processus est tué ou meurt.Ajouté: (et quelque chose sans pertinence supprimé)
Le toujours présent (en cours d'exécution, mais surtout d'inactivité) démon approche a l'avantage d'éliminer la possibilité d'instances simultanées du script en cours d'être lancé par cron automatiquement.
Cependant, vous êtes responsable de la gestion du timing correctement, comme dans le cas de il y a un chevauchement (c'est à dire une exécution précédente est toujours en cours d'exécution, tandis qu'un nouveau déclencher se produit). Cela peut vous aider à décider si vous souhaitez utiliser un fork de démon ou de non-bifurcation de la conception. Les Threads n'apportent aucun avantage dans ce scénario, donc, il n'est pas nécessaire d'envisager leur utilisation.
Ce n'élimine pas complètement la possibilité de multiples processus en cours d'exécution, mais que d'un problème commun à de nombreux démons. La solution classique est d'utiliser un sémaphore comme mutuellement exclusifs verrou sur un fichier, pour éviter une deuxième instance en cours d'exécution. Le fichier de verrouillage est automatiquement oublié lorsque le processus se termine, dans le cas d'un arrêt anormal (par ex. panne de courant) il n'y a pas de nettoyage nécessaire de la serrure elle-même.
Une approche à l'aide de module Fcntl, et à l'aide d'un Perl
sysopen
avec unO_EXCL
drapeau (ouO_RDWR | O_CREAT | O_EXCL
) a été donné par Greg Bacon. Les seules différences que j'aimerais apporter sont les combiner de verrouillage exclusif dans le sysopen appel (c'est à dire utiliser les drapeaux, j'ai suggéré), et retirez-le ensuite redondantflock
appel. Oh, et je voudrais suivre les UNIX (& Linux FHS) du système de fichiers et les conventions de nommage de/var/run/daemonname.pid
.Une autre approche serait d'utiliser djb de daemontools ou similaire à "daemonize" la tâche.