2

私がやろうとしているのは、特定の時間にスクリプトを実行することです。ほとんどの場合、実行から短い時間枠、たとえば約10〜15分でスクリプトを実行すると機能します。したがって、タイマースクリプトを実行し、10〜15分後にコマンドを実行します。

これが私が使用しているコードです:

import time
import myscript
from sys import exit

while 1:
        if time.strftime("%H") == "7" and time.strftime("%M") == "15":
                myscript.main()
                exit()

私が欲しいのは、スクリプトを毎日朝に実行することです。その日の後半にコンピューターにアクセスすると、スクリプトがこのプロセスでスタックしていることがわかります。

Ubuntu 12.0464ビットボックスとcygwinがインストールされたWindowsXPボックスの2台のマシンでこれを試しましたが、どちらも同じ問題を示しています。コンピューターを離れるときは、コンピューターをロックするだけで、スタンバイ状態にすることはありません。スクリプトを実行してロックしてから、簡単にロックを解除してみましたが、スクリプトが正常に実行されるため、これは問題ではないことがわかります。

また、私がコンピューターにアクセスすると、実行速度が非常に遅く、このスクリプトは30〜50%の範囲で非常に多くのCPU使用率を使用しているようです。

他に何が欠けているのですか、それともこれは理想的な方法ではありませんか?

4

2 に答える 2

2

そこに眠っていないことは、あなたのシステムがおかしくなる理由を説明しています。それはあなたのCPUが行くことができるのと同じくらい速く回転しています。

特定の時間に関数を実行するラッピングスクリプトを試しているだけの場合は、次のようにすることができます。

from datetime import datetime
import time

while True:
    now = datetime.now()
    if now.hour == 7 and now.minute == 15:
        foo()
    time.sleep(10)

しかし、ここで考えるべき大きな問題があります。foo()時間がかかったり、独自の操作ができなくなったりした場合はどうなりますか?

あなたのケースで起こっているかもしれないことは、あなたの睡眠(60秒に設定されている)が本当にその分のウィンドウを逃したかもしれないということです。分を複数回チェックすることを確認するために、少しずつスリープする必要があります。

これとは別に、cronジョブを使用します。スケジュールされたタスクを実行することを目的としています。cronは、とにかく使用していると述べたcygwinシェルに存在します。Windowsでのcrontabの設定については、こちらを参照してください

于 2012-08-17T22:30:42.670 に答える
1

更新:午前7時15分以降の最初の機会に1回だけ実行する必要がある場合:

now = datetime.now()
dt = now.replace(hour=7, minute=15) #note: ignore seconds, microseconds
if dt < now:
   dt += timedelta(days=1) #note: might miss by an hour on DST transition day
assert dt >= now
delay = (dt - datetime.now()).total_seconds()
Timer(delay, myscript.main).start()

main午前7時15分、または午前7時15分にスリープ状態の場合は、コンピューターが起動した直後に実行されます。


他の人がcronなどの既存のソリューションを言っているように、Windowsタスクスケジューラは、指定された時間にスクリプトを実行するのに適している場合があります。

明示的なビジーループを回避するには、を使用できますthreading.Timer()

#!/usr/bin/env python
from datetime  import datetime, timedelta
from threading import Timer

import myscript

def run_at(dt, func, step=timedelta(days=1), tolerance=timedelta(minutes=1)):
    if abs(dt - datetime.now()) < tolerance:
       func() # don't schedule if it raises an exception

    now = datetime.now()
    while dt < now:
        dt += step

    delay = (dt - datetime.now()).total_seconds()
    Timer(delay, run_at, [dt, func]).start()

dt = datetime.now().replace(hour=7, minute=15)
run_at(dt, myscript.main)

毎日現地時間の7:15にメイン関数を呼び出します。

前の通話がまだ完了していない場合、またはコンピュータが7:15に一時停止されている場合は、通話をスキップします。DST移行日をスキップする場合があります。

システムクロックが呼び出し間で前後に設定されている場合は、機能するはずです。

より複雑なスケジューリング仕様を処理するには、Pythonのcrontab構文を使用できます() 。

于 2012-08-18T02:04:03.340 に答える