2017-09-21 2 views
1

私は、毎秒10回、呼び出したい機能を持っています。私はこのようなコードでスタート:これは、[OK]を動作しますが、the_operationがあるため、操作そのものを実行する時間を、わずかに少ないことが多い所望のものより呼ばれ与えられた平均スループットを維持しながら、さまざまな時間がかかる操作を実行する方法

while True: 
    the_operation() 
    time.sleep(1.0/TIMES_PER_SECOND) 

。私たちは、代わりにこのようなコードを見て作ることができます。

while True: 
    t = time.time() 
    the_operation() 
    time_to_sleep = 1.0/TIMES_PER_SECOND - (time.time() - t) 
    if time_to_sleep > 0: 
     time.sleep(time_to_sleep) 

をこれは良いですが、それでも十分ではない良い - ループを実行するための時間は考慮されていない、とthe_operationは長い1/TIMES_PER_SECONDよりも有意に取るように発生した場合ある反復では、スループットが低すぎます。平均操作は1/TIMES_PER_SECOND未満ですが、コードは時間がかかる場合を処理する必要があります。

平均して指定されたレートでthe_operationを呼び出すための良いパターンは何ですか?

答えて

0

操作が正しい速度で実行されている場合に、予想される時間を記録します。これにより、実際の時間と希望の時間を比較し、それが肯定的であればその睡眠をとることができます。それが否定的なものであれば、私たちが追いつくまで、睡眠のない状態で連続的に運転されます。

expected = time.monotonic() 
while True: 
    the_operation() 
    expected += 1.0/TIMES_PER_SECOND 
    time.sleep(max(0, expected - time.monotonic())) 

これは、遅延は、ループ内の任意の時点で発生した場合でも(オペレーティング・システムは、当社のプロセスをスケジュールしないことに決めたと言う)に動作します。

time.monotonic()は、time.time()の代わりに使用する必要があります。後者は時間調整が必要であるため、monotonic()はシステムクロックを調整しても常に一定レートで単調増加します。

操作が非常に遅く、目的のスループットを達成できない場合は、通知を受けることをお勧めします。 sleep/max構造体を次のように置き換えることができます:

adjust = expected - time.monotonic() 
if adjust > 0: 
    time.sleep(adjust) 
elif adjust < -10: 
    print("Can't keep up!", -adjust, "seconds behind.") 
関連する問題