4

私が望むのは、関数の所要時間に関係なく、毎秒関数を実行できるようにすることです (常に 1 秒未満にする必要があります)。いくつかのオプションを検討しましたが、どれが最適かわかりません。

遅延関数を使用するだけでは、関数の実行にかかる時間が考慮されません。

関数の時間を計り、それを 1 秒から差し引き、残りの遅延を補うと、時間の計算は考慮されません。

threading.timer を使用してみました (これがどのように機能するかについてはよくわかりません) が、1 秒よりも遅いように見えました。

threading.timer をテストするために試したコードは次のとおりです。

def update(i):
    sys.stdout.write(str(i)+'\r')
    sys.stdout.flush()
    print i
    i += 1
    threading.Timer(1, update, [i]).start()

関数にかかる時間の長さに関係なく、これを行う方法はありますか?

4

6 に答える 6

9

これで十分ですし、時間の経過とともに精度が変動することもありません。

import time

start_time = time.time()
interval = 1
for i in range(20):
    time.sleep(start_time + i*interval - time.time())
    f()
于 2012-05-30T09:12:14.873 に答える
7

threading.Timer (以下のコードを参照) を使用するアプローチは、実際には使用しないでください。間隔ごとに新しいスレッドが起動され、このループを完全に停止することはできません。

# as seen here: https://stackoverflow.com/a/3393759/1025391
def update(i):
  threading.Timer(1, update, [i+1]).start()
  # business logic here

バックグラウンド ループが必要な場合は、他の回答で説明されているように、ループを実行する新しいスレッドを起動することをお勧めします。停止信号を受信できるものはjoin()、最終的にスレッドを実行できます。

この関連する回答は、これを実装するための優れた出発点のようです。

于 2012-05-30T09:15:24.870 に答える
3

常に 1 秒未満しかかからない場合f()は、1 秒の境界で (ドリフトなしで) 実行します。

import time

while True:
    time.sleep(1 - time.monotonic() % 1)      
    f()

アイデアは、同様の質問に対する@Dave Roveの回答からのものです。

それがどのように機能するかを理解するために、例を考えてみましょう:

  1. time.monotonic()戻り13.7time.sleep(0.3)呼び出されます
  2. f()(±some error)14秒前後に呼び出されます (time.monotonic()エポックから)
  3. f()実行され、0.1(< 1) 秒かかります
  4. time.monotonic()14.1数秒後に返され、time.sleep(0.9)呼び出されます
  5. 15ステップ 2. は約数秒 (time.monotonic()エポックから)繰り返されます
  6. f()が実行され、0.3(< 1) 秒かかります (注: 値はステップ 2 とは異なります)。
  7. time.monotonic()戻ってきて15.3呼び出さtime.sleep(0.7)れる
  8. f()秒前後で呼び出され16、ループが繰り返されます。

各ステップで、(タイマーf()に従って) 1 秒の境界で呼び出されます。time.monotonic()エラーは蓄積されません。ドリフトはありません。

参照: Python で関数を定期的に実行する方法 (tkinter を使用)

于 2016-02-28T19:20:50.913 に答える
1

これはどうですか: 各実行の後、(1.0 - launch interval)数秒間スリープ状態にします。を変更することで、終了条件を変更できますwhile True:。ただし、関数の実行に 1 秒以上かかる場合、これはうまくいきません。

from time import time, sleep

while True:
    startTime = time()
    yourFunction()
    endTime = time()-startTime
    sleep(1.0-endTime)
于 2012-05-30T09:29:55.323 に答える