cron Vs. sleep - quelle est la meilleure en termes d'utilisation efficace du processeur / de la mémoire?

18

L'affaire:

J'ai besoin d'exécuter certaines commandes / scripts à certains intervalles de temps et pour cela, j'ai deux options:

  1. mettre en place un cron-job
  2. implémenter une boucle avec sleepdans le script lui-même.

Question:

Quelle est la meilleure option du point de vue de la consommation des ressources, pourquoi? Est-ce cronla meilleure façon? Cron utilise-t-il une sorte de déclencheurs ou quelque chose qui le rend efficace par rapport à l'autre? Quelle procédure cron utilise-t-elle pour vérifier et démarrer les travaux?

précis
la source

Réponses:

14

Utilisez cron car c'est une pratique meilleure et plus standard. Au moins si c'est quelque chose qui se déroulera régulièrement (pas seulement quelque chose que vous avez corrigé ensemble en une minute). cronest une manière plus propre et plus standard. C'est aussi mieux car il exécute le shell détaché d'un terminal - aucun problème avec la terminaison accidentelle et les dépendances avec d'autres processus.

Concernant les ressources: CPU: Les deux processus sont en veille - lorsqu'ils dorment, ils ne gaspillent pas le CPU. cronse réveille plus fréquemment pour vérifier les choses, mais il le fait quand même (plus pour votre processus). Et c'est une charge négligeable, la plupart des démons se réveillent de temps en temps. Mémoire: Vous avez probablement cronexécuté indépendamment de ce processus, donc ce n'est pas du tout une surcharge. Cependant, cron ne démarre le shell que lorsque le script est appelé, tandis que votre script reste chargé en mémoire (un processus bash avec environnement - quelques kilo-octets, à moins que vous ne chargiez tout dans les variables du shell).

Dans l'ensemble, pour les ressources, cela n'a pas d'importance.

orion
la source
19

Utilisez cron(ou anacron).

Cron est conçu pour exécuter des choses à intervalles. C'est la seule chose qu'il fait, et il y a eu beaucoup de travail mis sur cron pendant de nombreuses années pour en faire ce qu'il est aujourd'hui.

Les chances que vous allez écrire un meilleur planificateur dans votre script sont en fait nulles. L'utilisation de cron fonctionnera mieux, évitez d'avoir du code inutile dans votre script et gardez votre code concis et plus maintenable.

Ne réinventez pas la roue si vous n'en avez pas besoin.

bahamat
la source
10

Il y a déjà de bonnes réponses cronet sleepperformances, mais je veux ajouter une sorte de comparaison de fonctionnalités.

Pro cron:

  • fonctionnant déjà sur les systèmes Unix / Linux
  • stable et éprouvé
  • conçu pour les processus d'arrière-plan
  • s'exécute à partir du démarrage du système, tout comme votre script, une fois installé
  • entrée plus facile des cycles à long terme (heures, jours, semaines)
  • permet des répétitions complexes à long terme ("un dimanche sur deux à 5 h 35")

Pro sleep:

  • plus facile à maintenir dans un script
  • plus facile pour les processus de premier plan
  • permet des temps de sommeil plus courts et plus précis qu'une minute
  • permet des cycles de sommeil / d'action complexes ("exécuter cette partie, puis dormir 10 secondes, puis exécuter l'autre partie et dormir deux heures")
Dubu
la source
4

Cron utilise-t-il une sorte de déclencheurs ou quelque chose qui le rend efficace par rapport à l'autre?

J'ai regardé cat /proc/`pidof crond`/stack. Après l'avoir imprimé plusieurs fois de suite, je vois que ça cronddort juste dans hrtimer_nanosleep.

>cat /proc/`pidof crond`/stack
[<ffffffff810a0614>] hrtimer_nanosleep+0xc4/0x180
[<ffffffff810a073e>] sys_nanosleep+0x6e/0x80
[<ffffffff8100b072>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff

sleep l'utilitaire utilise le même appel système.

>sleep 100 &
[1] 12761
>cat /proc/12761/stack
[<ffffffff810a0614>] hrtimer_nanosleep+0xc4/0x180
[<ffffffff810a073e>] sys_nanosleep+0x6e/0x80
[<ffffffff8100b072>] system_call_fastpath+0x16/0x1b
[<ffffffffffffffff>] 0xffffffffffffffff

Je suppose que les deux utilitaires ( crond& sleep) doivent avoir une faible utilisation du processeur et si vous avez besoin d'imiter, cronvous pouvez certainement utilisersleep .

Mise à jour. Il vaut mieux observer crondl’activité de

strace -p `pidof crond`
Sergei Kurenkov
la source
Réponse très sous-estimée.
Hashim
3

La principale différence que vous recherchez est qu'elle cronne fonctionne pas constamment. Comme expliqué dans man cron:

   cron then wakes up every minute, examining all stored crontabs,  check
   ing  each  command  to  see  if it should be run in the current minute.
   When executing commands, any output is  mailed  to  the  owner  of  the
   crontab (or to the user named in the MAILTO environment variable in the
   crontab, if such exists).  The children copies of  cron  running  these
   processes  have their name coerced to uppercase, as will be seen in the
   syslog and ps output.

En d'autres termes, cronne sera démarré qu'une fois par minute et il testera s'il doit être exécuté. Votre approche de sommeil, d'autre part, nécessiterait votre sleepcommande réelle , votre shell, votre terminal et lewhile boucle (ou autre) soient exécutés en même temps.

Même s'ils lançaient le même nombre de processus, ce cronserait mieux. Il est écrit précisément pour cela par des gens qui ont tendance à être très bons dans leur travail. Il est destiné à en faire un meilleur travail qu'une simple boucle shell.

terdon
la source
5
Les deux dorment - il n'y a effectivement aucune différence. Votre coquille qui dort ne se réveille également que lorsque le sommeil expire. Il n'utilise pas plus de CPU que cron. Si quoi que ce soit, cron se réveille plus fréquemment car il doit vérifier si quelque chose a changé, tandis que votre processus dort tout le temps. Cependant, vous obtenez un autre processus bash chargé (en plus de cron, qui s'exécute quand même), donc il utilise un peu plus de RAM (quelques ko).
orion
3

La différence vient du fait que lorsque vous ajoutez plus de scripts qui doivent dormir, vous vous retrouverez avec plus de processus en attente, au lieu d'un seul processus (cron) qui se réveille et exécute les scripts planifiés qui se ferment ensuite jusqu'à la prochaine exécution. Cron permet un processus spécialisé pour exécuter d'autres scripts à temps, plus cron vous permet de planifier relativement librement quand quelque chose doit être exécuté, les jours de la semaine ou du mois, des heures spécifiques, ou toutes les 5 minutes, etc.

* Le simple fait de revoir cela m'a fait penser à un autre avantage de cron. Tous les scripts qui s'exécutent périodiquement sont alors au même endroit, et il est facile de vérifier à partir de là quand et à quelle fréquence ils s'exécuteront. Sinon, vous devez vérifier les scripts individuels.

Benjamin Scherer
la source
1

Il existe déjà de bonnes réponses plus éclairées, mais je voulais simplement souligner qu'avec sleep, vous avez la possibilité de geler le processus pendant une durée variable, par exemple en fonction de certaines autres variables.

Si j'écris un script pour vérifier le pourcentage de batterie qui reste et notify-sends'il est en dessous du niveau critique prédéfini, je peux faire le script sleeppour la durée qui est fonction du niveau de batterie actuel en pourcentage au lieu de vérifier la batterie tous les une ou deux minutes avec l'aide de cron même quand je sais que c'était 80% lors de la dernière vérification.

Battery_notify.sh

#!/bin/bash
CRIT=15
while true; do
    # current battery level
    BAT_LEVEL=`acpi -b |grep -Eo "[0-9]+%"|grep -Eo "[0-9]+"`
    interval=$((($BAT_LEVEL -$CRIT) * 120)) # loose estimate of backup time for each percentage of battery charge.
    # Is AC plugged in?
    state=`acpi -b |grep -Eo "[A-Za-z]+harging"` 
    #only notify if not Plugged in
    if [ "$state" = "Discharging" ] ; then
        # is battery below CRIT level?
        if [ $BAT_LEVEL -le $CRIT ]; then
        aplay ~/apert.wav &
        notify-send "Battery-Low!!!" -i /home/bibek/batt.png -t 900
        sleep 100  # nag me each 100 secs untill I plug the thing 
        else
            sleep $interval
        fi
    else
        # if plugged in sleep 
        if [ $BAT_LEVEL -le $CRIT ]; then
            sleep $interval
        else
            # to check if the AC is unplugged before battery gains charge above CRIT.
            sleep 100 
        fi
    fi
    done
Bibek_G
la source
0

L'utilisation sleepau lieu de cronpour un seul travail peut être plus efficace. Mais comme vous avez généralement en croncours d' exécution dans tous les cas, son utilisation est gratuite ou assez proche car cela ne fait aucune différence. Donc, à moins que vous ne soyez sur un cronsystème embarqué autrement libre, je choisirais cron.

MvG
la source