Pythonのsleepでミリ秒を指定する方法

【Python】sleepでミリ秒を指定する方法

公開: 更新:
CodeCampが提供するDX人材育成が可能なプログラミングやITが学べる公開講座

Pythonで処理をミリ秒単位で一時停止させる場面は、スクレイピングのアクセス間隔制御や高頻度なデータ処理など、正確なタイミング制御が求められる文脈で頻繁に発生します。待機処理の実装でよく使われるのが「timeモジュールのsleep」で、小数を指定することによって1秒未満の細かい待機時間を簡単に実現できます。

この記事では、Pythonにおけるミリ秒単位の待機処理の基本的な使い方を解説していきます。指定した時間通りに止まらないOSのタイマー解像度の問題や高精度な時間制御を実現する代替手法など、サンプルコード付きで解説していきますので、ぜひ参考にしてください。



Pythonのsleep関数でミリ秒を指定する方法

標準ライブラリのtimeモジュールを活用すると、プログラムの実行を任意の間隔で一時停止できます。引数に小数を渡すことによって、1秒未満の細かい数値を指定可能です。

ここでは、以下の2つの実装パターンについて解説します。

  • 小数を用いてミリ秒を指定する実装例
  • APIリクエスト間隔を制御する実装例

それぞれの具体的な記述方法と活用場面を見ていきましょう。

小数を用いてミリ秒を指定する実装例

Pythonの処理を一時停止させる場合、組み込みモジュールをインポートして待機時間を秒単位で渡します。引数に0.001を指定すると、理論上は1ミリ秒の待機処理として機能します。

小数を活用して待機時間を設定する基本的な記述方法は、以下のとおりです。

import time

# 1ミリ秒(0.001秒)待機する
time.sleep(0.001)

# 500ミリ秒(0.5秒)待機する
time.sleep(0.5)

上記のコードでは、指定した秒数だけカレントスレッドの実行を一時的にブロックし、CPUの利用権限をOSに返却しています。指定時間は最小の待機時間として扱われ、OSのスケジューリングの影響で常に正確なミリ秒で再開されるわけではない点を把握しておくと役立ちます。

APIリクエスト間隔を制御する実装例

外部サーバーへ連続してアクセスする際、短時間に大量の通信を発生させないための負荷軽減策として待機処理を利用します。適切な間隔を空けることによって、アクセス制限や遮断の対象となるリスクを回避できます。

ループ処理の中で一時停止を挟み、リクエスト間隔を一定に保つコードは以下のようです。

import time

api_endpoints = ["endpoint1", "endpoint2", "endpoint3"]

for endpoint in api_endpoints:
    # APIへリクエストを送信するダミー処理
    print(f"{endpoint}へリクエストを送信しました")
    
    # サーバー負荷を軽減するために100ミリ秒待機する
    time.sleep(0.1)

上記のコードでは、リスト内の要素を処理するたびに0.1秒の待機時間を設け、意図しないサーバーへの負荷集中を防いでいます。定期的なデータ収集やアニメーションのフレームレート調整など、一定の周期を持たせたい場面でも同様に適用できます。


Python研修一覧はこちら

目的に合うPython研修を一覧形式から探したい方は、ぜひご利用ください。

Python研修を比較する

Java研修一覧はこちら

目的に合うJava研修を一覧形式から探したい方は、ぜひご利用ください。

Java研修を比較する

PHP研修一覧はこちら

目的に合うPHP研修を一覧形式から探したい方は、ぜひご利用ください。

PHP研修を比較する

新入社員研修

目的に合う新入社員研修を一覧形式から探したい方は、ぜひご利用ください。

新入社員研修を比較する

全ての研修からも探したい方はこちら

Pythonのミリ秒待機が不正確になる原因

Pythonで短い時間を待機させる際、指定した時間通りに止まらない現象が頻繁に発生します。これは、ハードウェアやシステムの仕様が大きく関わっています。

  • OSのタイマー分解能による要因
  • ブロッキング処理の仕様による要因

これらの要因を把握しておくと役立ちます。特にWindows環境やシステム負荷が高い状況では、遅延が顕著に現れる傾向があります。

ここでは、待機時間が不正確になる根本的な理由を順番に解説していきます。

OSのタイマー分解能による要因

以下のコードは、0.001秒の待機を指定して実際の経過時間を高精度に計測する例です。

import time

start_time = time.perf_counter()
time.sleep(0.001)
end_time = time.perf_counter()

print(end_time - start_time)

上記のコードでは、Python 3.11未満かつWindowsのタイマー分解能が改善される前の環境(Windows 8.1未満)で実行すると、約15.6ミリ秒前後の経過時間が表示されるケースがあります。これは、Windowsのデフォルトのタイマー分解能が約15.6ミリ秒であることに起因しています。

ただし、Python 3.11以降(Windows 8.1以降、公式What's New 3.11より)では内部実装が改善されており、この遅延は大幅に軽減されています。

指定した時間はあくまで最小の待機時間として扱われます。Pythonの公式ドキュメントでも、オペレーティングシステムのスケジューラに依存するため精度が落ちる場合があると説明されています。

PythonのバージョンやWindowsのバージョン、システムの負荷状況によって実際の待機時間は変動するため、環境ごとの差異を考慮した実装が求められます。

ブロッキング処理の仕様による要因

以下のコードは、ループ内で待機処理を実行して経過時間を測定する例です。

import time

for _ in range(3):
    start = time.perf_counter()
    time.sleep(0.01)
    end = time.perf_counter()
    print(end - start)

上記のコードでは、実行のたびに待機時間にばらつきが生じます。精度低下の主要因は、OSのスケジューラによる再開タイミングの不確定性です。

システムが別のタスクにCPUを割り当てた場合、再度プログラムに処理が戻るまでに時間がかかるため、指定値よりも長い待機時間になるケースが発生します。

なお、CPythonのデフォルトビルドでは、time.sleep()はGIL(Global Interpreter Lock、Pythonインタープリタが同時に実行できるスレッドを1つに制限するロック機構)を解放するため、待機中も他のスレッドは動作できます。スレッド全体が停止するわけではない点を把握しておくと役立ちます。

厳密なタイミング制御が求められる場面では、次のセクションで解説する代替手法の検討が必要です。

Pythonで高精度なミリ秒待機を実現する手法

標準の待機処理では、OSの仕様や実行環境の影響を受けて精度が低下するケースがあります。より厳密な時間制御が求められる状況では、代替手段の導入が効果的な場合があります。

精度を改善できる可能性がある手法として、以下のアプローチが存在します。要件に応じて適切なものを選択してください。

  • OSのタイマー分解能を一時的に向上させる(Python 3.10以前のWindows向け)
  • CPUを占有して待機時間を厳密に制御する
  • 最新バージョンのPythonが提供する機能を利用する

各手法にはそれぞれメリットとデメリットがあります。システム全体の負荷や実行環境を考慮して導入を検討しましょう。

ここでは、それぞれの具体的な実装方法や特徴について、サンプルコードを交えて解説していきます。


Python基礎・実践(Django)

企業・法人向けのPython研修では、基礎から応用まで体系的に学べます。

Python研修の詳細

DX社員研修

企業・法人向けのDX研修では、実務に繋がるリスキリングでITレベルを向上させます。

DX研修の詳細

Javaエンジニア育成研修

企業・法人向けのJavaエンジニア育成研修では、Javaの基礎から応用まで確実に習得できます。

Java研修の詳細

新卒・新入社員向け研修

企業・法人に新入社員・新卒社員に向けたプログラミング研修を提供しています。

新入社員研修の詳細

コードキャンプのIT研修を全て見る

OSのタイマー精度を変更する手法

Windows環境において、標準のタイマー分解能は約15.6ミリ秒に設定されています。この分解能をctypesライブラリを用いて一時的に変更し、精度を向上させます。

以下のコードは、タイマー精度を1ミリ秒に変更してから待機処理を実行する例です。

import time
import ctypes

# タイマー精度を1ミリ秒に変更
ctypes.windll.winmm.timeBeginPeriod(1)

try:
    start = time.perf_counter()
    time.sleep(0.001)
    end = time.perf_counter()
    print(f"待機時間: {end - start:.4f}秒")
finally:
    # タイマー精度を元に戻す
    ctypes.windll.winmm.timeEndPeriod(1)

上記のコードでは、timeBeginPeriodを呼び出して精度を変更しています。処理が完了した後は、システムへの影響を防ぐために必ずtimeEndPeriodで設定を戻してください。

このアプローチは主にPython 3.10以前のWindows環境での対策として有効です。timeBeginPeriodのタイマー分解能への影響は、Windowsのバージョンによって異なります。

Windows 10 version 2004より前ではシステム全体のタイマー分解能を変更するため、他のプロセスにも影響を与えます。一方、Windows 10 version 2004以降では主に呼び出したプロセスに対してのみ適用されるよう仕様が変更されています。

また、Microsoftの公式ドキュメントでは過度な使用がシステム全体の消費電力を増加させる可能性があると説明されているため、必要な期間のみ使用し確実に設定を元に戻す実装が求められます。Python 3.11以降(Windows 8.1以降)ではtime.sleep()自体が改善されているため、このアプローチが必要なシーンは限定的です(詳細は「Python 3.11以降の機能を利用する手法」を参照)。

無限ループを利用する手法

通常の待機処理はCPUの利用権限をOSに返却するため、再開時に遅延が発生しやすくなります。この問題を回避するために、無限ループ内で現在時刻を監視し続ける「Busy-wait(Spin loop)」という手法が用いられます。

無限ループを利用して1ミリ秒の待機を実現する使い方は以下の通りです。

import time

def spin_sleep(target_seconds):
    target_time = time.perf_counter() + target_seconds
    while time.perf_counter() < target_time:
        pass

start = time.perf_counter()
spin_sleep(0.001)
end = time.perf_counter()
print(f"待機時間: {end - start:.4f}秒")

上記のコードでは、timeモジュールのperf_counterを使って経過時間を高精度に計測しています。CPU消費と引き換えに短い待機のばらつきを抑えやすい手法ですが、OSのプリエンプションにより遅延が生じる可能性はゼロではありません。

待機中は1CPUコアを大きく消費し、使用率が高止まりしやすいというデメリットがあります。これは通常時にOSへCPUを返却するtime.sleep()とは対照的な挙動です。

他のプロセスの動作を妨げる可能性があるため、短時間・限定用途でのみ使用し、通常の実装では非推奨の手法として扱ってください。

Python 3.11以降の機能を利用する手法

Python 3.11では、標準の待機処理の内部実装が改善されています。Unix環境においては、マイクロ秒の解像度だったものがナノ秒の解像度へと向上しています(clock_nanosleepnanosleepを利用)。

さらにWindows環境でも、Python 3.11以降(Windows 8.1以降、What's New 3.11より)ではtime.sleep()がhigh-resolution waitable timerを使用するように改善されています。なお、現行の公式timeドキュメントではWindows 10以降と記載されており、公式ドキュメント間で表記に差異がある点に留意してください。

従来の約1ミリ秒分解能から100ナノ秒分解能へと大幅に向上しており、最新環境では追加の手法を使わずとも精度が改善される場合があります。

新しいバージョンの機能を活かして待機処理を実行するコードは以下の通りです。

import time

# Python 3.11以降(Windows 8.1以降 / Unix)で内部実装が改善
start = time.perf_counter()
time.sleep(0.001)
end = time.perf_counter()

print(f"待機時間: {end - start:.4f}秒")

上記のコードでは、標準の関数を呼び出すだけでPython 3.11以降の改善された実装が自動的に適用されます。ただし、この内部実装の変更はOSスケジューリングによる遅延を完全には排除しておらず、指定時間ぴったりの待機を保証するものではない点を把握しておくと役立ちます。

Pythonのsleep関数によるミリ秒待機に関するよくある質問

time.sleepとasyncio.sleepのどちらを使えばよいですか?

同期処理(通常のプログラム)ではtime.sleepを使用し、asyncioを用いた非同期処理ではasyncio.sleepを使用します。非同期環境でtime.sleepを使うと、待機中に他の非同期タスクへ処理を譲れないため、プログラム全体が意図せずブロックされます。

async関数の中で待機処理を書く場合は、await asyncio.sleep(秒数)の形式で記述してください。通常の関数やスクリプトのトップレベルではtime.sleep(秒数)を使用するのが基本です。

time.sleep関数はCPUの使用率を大幅に上げますか?

この処理はOSにCPUの利用権限を返却するため、待機中のCPU使用率が大幅に上がることはありません。呼び出したスレッドのみを停止させるブロッキングの動作が特徴で、CPythonのデフォルトビルドではGILを解放するため他のスレッドは待機中も動作できます。

ただし、より高精度なミリ秒単位の制御を求めて無限ループを利用する待機手法を採用した場合は、CPUコアを継続的に消費します。処理の精度とリソース負荷のトレードオフを考慮して実装手法を選択してください。

※上記コンテンツの内容やソースコードはAIで確認・デバッグしておりますが、間違いやエラー、脆弱性などがある場合は、コメントよりご報告いただけますと幸いです。

ITやプログラミングに関するコラム


ITやプログラミングに関するニュース

ブログに戻る

コメントを残す

コメントは公開前に承認される必要があることにご注意ください。

企業・法人向けのIT・プログラミング・生成AI研修を探す、比較する - IT・プログラミングを知って学べるコネクトメディア CodeCampが提供するDX人材育成が可能なプログラミングやITが学べる公開講座 - IT・プログラミングを知って学べるコネクトメディア コードキャンプが提供する無料で学べるプログラミングスクール講座 - IT・プログラミングを知って学べるコネクトメディア コードキャンプDX人材育成研修 - IT・プログラミングを知って学べるコネクトメディア 配属3ヶ月で30%の生産性向上を実現するいよぎんコンピュータサービスの新人研修に迫る - IT・プログラミングを知って学べるコネクトメディア 金融業界の業務効率化を加速するニッセイアセットマネジメントの生成AI×GAS活用研修事例 - IT・プログラミングを知って学べるコネクトメディア 【製造業のDX人材育成事例】デジタル人材の即戦力化を実現する、日本ガイシ株式会社の異動者向オンボーディング研修 - ITやプログラミングを知って学べるコネクトメディア フューチャーアーキテクト株式会社が実現した新入社員向けIT研修プログラムでタスクフォース制度が主体的な学びと成長を生み出す - IT・プログラミングを知って学べるコネクトメディア コードキャンプDX人材育成研修 - IT・プログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/【IT新入社員研修】オンラインとオフラインの最適バランスを実現したFutureOneの導入事例 - IT・プログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/【新入社員研修】柔軟なハイブリッド型Java研修で実現した新卒20名の成長と成果|サークレイス株式会社 - ITやプログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/現場により近いところにデジタルを根付かせるDX基礎講座研修|株式会社ブリヂストン - ITやプログラミングを知って学べるコネクトメディア コードキャンプIT・プログラミング研修事例/業務の効率化・DX推進に向けたIT人材育成への第一歩|株式会社カナエ - ITやプログラミングを知って学べるコネクトメディア 企業・法人向けのIT・プログラミング研修 - ITやプログラミングを知って学べるコネクトメディア

新着記事

対象者別で探す

子供(小学生・中学生・高校生)向け
プログラミング教室検索する

子供(小学生・中学生・高校生)がロボットやプログラミング言語を学ぶことができるオフラインからオンラインスクールを検索、比較することが可能です。

子供(小学生・中学生・高校生)
プログラミング教室検索する

ITやプログラムなどの
最新情報を検索する

日々、新しいITやプログラミング言語の情報が流れていきますが、特定の情報を時系列でニュースやコラムを確認することができます。

ITやプログラムなどの
最新情報を検索する