web-dev-qa-db-ja.com

cron対スリープ-効率的なCPU /メモリ使用率の点でどちらが優れていますか?

ケース:

特定の時間間隔でいくつかのコマンド/スクリプトを実行する必要があり、そのために2つのオプションがあります。

  1. cron- jobを設定する
  2. スクリプト自体にsleepでループを実装します。

質問:

リソース消費の観点から、どちらがより良いオプションですか、なぜですか? cronがより良い方法ですか? cronは何らかのトリガーを使用していますか? cronはジョブの確認と開始にどのような手順を使用しますか?

17
precise

Cronを使用してください。これは、より適切で標準的な方法です。少なくともこれが定期的に実行されるものである場合(1分でパッチを当てただけではありません)。 cronは、よりクリーンで標準的な方法です。ターミナルから切り離されたシェルを実行するため、これも優れています-偶発的な終了や他のプロセスへの依存に関する問題はありません。

リソースについて:CPU:両方のプロセスがスリープします-スリープするとき、CPUを浪費しません。 cronは、物事をチェックするために頻繁に起動しますが、とにかくそれを実行します(プロセスではこれ以上ありません)。そして、これは無視できる負荷であり、ほとんどのデーモンは時々目を覚ます。メモリ:このプロセスに関係なくcronを実行している可能性があるため、オーバーヘッドはまったくありません。ただし、cronはスクリプトが呼び出されたときにのみシェルを起動しますが、スクリプトはメモリにロードされたままです(シェル変数にすべてをロードしない限り、環境でのbashプロセス-数キロバイト)。

全体として、リソースについては問題ではありません。

14
orion

cron(またはanacron)を使用します。

Cronは、物事を一定間隔で実行するように設計されています。それが唯一のことであり、長年に渡ってcronが今日の姿にするために多くの作業が行われてきました。

スクリプトでより優れたスケジューラを作成する可能性はほとんどありません。 cronを使用すると、より効果的に機能し、スクリプトに不要なコードが含まれるのを回避し、コードを簡潔で維持しやすくします。

必要がない場合は、ホイールを再発明しないでください。

19
bahamat

cronsleepのパフォーマンスについてはすでに良い答えがいくつかありますが、何らかの機能比較を追加したいと思います。

プロcron

  • unix/Linuxシステムですでに実行中
  • 安定して証明された
  • バックグラウンドプロセス用に設計
  • システムの起動時から実行され、インストールされたスクリプトも実行されます
  • 長期サイクル(時間、日、週)のより簡単な入力
  • 複雑な長期繰り返しを許可します(「毎週第2日曜日の午前5時35分」)

プロsleep

  • スクリプトで保守しやすい
  • フォアグラウンドプロセスの方が簡単
  • 睡眠時間を1分よりも短く正確にできる
  • 複雑なスリープ/アクションサイクルを許可します(「この部分を実行してから10秒スリープし、次に他の部分を実行して2時間スリープする」)
10
Dubu

Cronは何らかのトリガーを使用していますか?

cat /proc/`pidof crond`/stackを確認しました。数回連続して印刷したので、crondが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ユーティリティは同じシステムコールを使用します。

>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

私は両方のユーティリティ(crondsleep)のCPU使用率が低い必要があると想定しています。cronを模倣する必要がある場合は、sleepを使用できます。

更新。 crondの活動を観察することをお勧めします

strace -p `pidof crond`
5
user17530

探している主な違いは、cronが常に実行されていないことです。 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.

言い換えると、cronは1分に1回だけ開始され、実行する必要があるかどうかをテストします。一方、スリープアプローチでは、実際のsleepコマンド、シェル、ターミナル、およびwhile(またはその他の)ループを同時に実行する必要があります。

同じ数のプロセスを起動している場合でも、cronの方が適しています。それは彼らの仕事がとても上手である傾向がある人々によってこれのために正確に書かれています。単純なシェルループよりもうまく機能するはずです。

3
terdon

違いは、スリープする必要があるスクリプトを追加すると、スケジュールされたスクリプトを起動して実行する次の実行まで閉じる単一のプロセス(cron)ではなく、多くのプロセスが待機してスリープ状態になることです。 Cronでは、他のスクリプトを時間どおりに実行することに特化した1つのプロセスを使用できます。さらに、cronを使用すると、何かを実行する必要があるとき、曜日または月、特定の時間、または5分ごとなど、比較的自由にスケジュールできます。

*これをもう一度見ただけで、cronのもう1つの利点を思いつきました。定期的に実行されるすべてのスクリプトは1か所にあり、そこから、いつどのくらいの頻度で実行されるかを簡単に確認できます。それ以外の場合は、個々のスクリプトを確認する必要があります。

3

すでに十分な情報に基づいた適切な回答がありますが、sleepを使用すると、たとえば他のいくつかの変数の関数として、プロセスをさまざまな時間フリーズすることができることを指摘したいと思います。

バッテリーの残量を確認するスクリプトを記述している場合、notify-sendが事前定義のクリティカルレベルを下回っている場合は、スクリプトをsleepにして、次の関数を実行できます。最後にチェックしたときに80%であることがわかっている場合でも、cronを使用して1〜2分ごとにバッテリーをチェックするのではなく、現在のバッテリーレベルをパーセンテージで表示します。

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
1
Bibek_G

単一のジョブに対してsleepの代わりにcronを使用する方が効率的かもしれません。ただし、通常はcronを実行しているので、それを使用しても無料で利用できます。ですから、そうでなければcron- free組み込みシステムを使用しているのでなければ、cronを選びます。

0
MvG