私はそれに浮動小数点数を与えることができます
time.sleep(0.5)
しかし、それはどのくらい正確ですか?あげたら
time.sleep(0.05)
本当に50ミリ秒ほどスリープしますか?
回答:
time.sleep関数の精度は、基盤となるOSのスリープ精度に依存します。標準のWindowsのような非リアルタイムOSの場合、スリープできる最小間隔は約10〜13ミリ秒です。最小の10〜13ミリ秒を超えると、その時間から数ミリ秒以内に正確な睡眠が見られます。
更新:下記のドキュメントで言及されているように、ループでスリープを行うのが一般的です。これにより、早く目覚めたら必ずスリープに戻ります。
Ubuntuを実行している場合は、rtカーネルパッケージ(少なくともUbuntu 10.04 LTS)をインストールすることにより、(RT_PREEMPTパッチセットを使用して)擬似リアルタイムカーネルを試すことができることにも言及する必要があります。
編集:修正非リアルタイムLinuxカーネルの最小スリープ間隔は1ミリ秒から10ミリ秒に非常に近くなっていますが、非決定的な方法で変化します。
sleep()
、ドキュメントからより重要なことをしているときにWindowsとLinuxの両方でOSが何をしているかによって異なります。「一時停止時間は、システムの他の活動」。
オペレーティングシステムとカーネルの違いについては非常に正しいですが、Ubuntuには細分性がなく、MS7には1 msの細分性があります。異なるティックレートだけでなく、time.sleepの異なる実装を提案します。ちなみに、詳細な検査では、Ubuntuの粒度が1μsであることが示唆されていますが、これは、精度の測定に使用するtime.time関数が原因です。
ドキュメントから:
一方、精度は
time()
、sleep()
同等のUnix の精度 より優れています。時刻は浮動小数点数として表され、time()
利用可能な最も正確な時刻を返し(利用可能な場合はUnixgettimeofday
を使用)、sleep()
ゼロ以外の小数の時刻を受け入れます(Unixselect
が使用されます)これを実装するには、可能な場合)。
そして、より具体的に WRT sleep()
:
指定された秒数の間、実行を一時停止します。引数は、より正確なスリープ時間を示す浮動小数点数にすることができます。キャッチされたシグナルは、そのシグナルのキャッチルーチンの次の実行を終了するため、実際の一時停止時間は要求された時間よりも短い場合があり
sleep()
ます。また、一時停止時間は、システム内の他のアクティビティーのスケジューリングのために、要求された時間よりも任意の量だけ長くなることがあります。
Wilbertの回答に対する私のフォローアップを以下に示します。MacOS X Yosemiteについても同様です。まだあまり言及されていないためです。
多くの場合、スリープ時間はリクエストした時間の約1.25倍であり、リクエストした時間の1倍から1.25倍の間でスリープすることもあります。要求した時間の1.25倍を大幅に超えてスリープすることはほとんどありません(1000サンプルの2倍)。
また、(明示的には表示されていません)1.25の関係は、約0.2ミリ秒を下回るまではかなりうまくいくようです。その後、少しあいまいになります。さらに、実際の時間は、要求された時間が20ミリ秒を超えた後、要求よりも約5ミリ秒長く落ち着くようです。
繰り返しになりますがsleep()
、OS Xの実装はWindowsやWilkerカーネルが使用していたLinuxカーネルとはまったく異なるようです。
見つけてみませんか:
from datetime import datetime
import time
def check_sleep(amount):
start = datetime.now()
time.sleep(amount)
end = datetime.now()
delta = end-start
return delta.seconds + delta.microseconds/1000000.
error = sum(abs(check_sleep(0.050)-0.050) for i in xrange(100))*10
print "Average error is %0.2fms" % error
ちなみに、どちらのLinuxマシンでも、HTPCで約0.1ミリ秒、ラップトップで2ミリ秒程度のエラーが発生します。
小さな修正ですが、信号によって睡眠が早く終了する可能性があると何人かが述べています。では3.6のドキュメントは言います、
バージョン3.5で変更:シグナルハンドラーが例外を発生させた場合を除いて、スリープによってシグナルが中断された場合でも、関数は少なくとも数秒スリープします(根拠についてはPEP 475を参照)。
sleep()について何も保証することはできませんが、少なくとも、あなたが伝えた限り、スリープ状態になるよう最善を尽くします(信号は、タイムアップする前にスリープを終了させることができます。長いです)。
確かに、標準のデスクトップオペレーティングシステムで取得できる最小値は約16ミリ秒(タイマーの粒度とコンテキストスイッチまでの時間)になりますが、提供された引数からの%偏差は、試行時に重要になる可能性があります。数十ミリ秒間スリープします。
シグナル、GILを保持している他のスレッド、カーネルスケジューリングの楽しみ、プロセッサ速度のステッピングなどはすべて、スレッド/プロセスが実際にスリープしている期間に大混乱をもたらす可能性があります。
def start(self):
sec_arg = 10.0
cptr = 0
time_start = time.time()
time_init = time.time()
while True:
cptr += 1
time_start = time.time()
time.sleep(((time_init + (sec_arg * cptr)) - time_start ))
# AND YOUR CODE .......
t00 = threading.Thread(name='thread_request', target=self.send_request, args=([]))
t00.start()
変数を使用してスリープ()の引数を渡さないでください。スリープ()に直接計算を挿入する必要があります
そして私の端末の復帰
1─────17:20:16.891───────────────────
2─────17:20:18.891───────────────────
3─────17:20:20.891───────────────────
4─────17:20:22.891───────────────────
5─────17:20:24.891───────────────────
....
689───17:43:12.891────────────────────
690───17:43:14.890────────────────────
691───17:43:16.891────────────────────
692───17:43:18.890────────────────────
693───17:43:20.891────────────────────
...
727───17:44:28.891────────────────────
728───17:44:30.891────────────────────
729───17:44:32.891────────────────────
730───17:44:34.890────────────────────
731───17:44:36.891────────────────────