Pythonのsleep関数は、プログラムの実行を一時的に停止させる重要な機能です。処理の間隔調整、タイミング制御、APIリクエストの制限など、多くの実用的なシナリオで活用できます。本記事では、sleep関数の基本的な使い方から応用例、注意すべき精度の問題やマルチスレッド環境での動作まで、実践的なコード例を交えて解説します。
sleep関数とは
Pythonのsleep関数は、timeモジュールに含まれる関数で、プログラムの実行を指定した秒数だけ一時停止させるために使用されます。これはプログラムの処理速度を調整したり、特定の時間間隔でタスクを実行したりする場合に非常に便利です。
sleep関数を使用するには、まずtimeモジュールをインポートする必要があります。このモジュールには時間に関連する様々な機能が含まれており、その中のsleep関数を利用することでプログラムの実行を一時的に停止することができます。
構文
sleep関数の基本的な構文は非常にシンプルです。
import time
time.sleep(秒数)
ここで「秒数」は、プログラムを一時停止させる時間を秒単位で指定します。この値は整数だけでなく、小数点以下の値(浮動小数点数)も指定可能です。例えば、0.5を指定すると0.5秒間プログラムが一時停止します。
例
基本的な使い方
以下は、sleep関数の最も基本的な使用例です。このコードは「こんにちは」と表示した後、2秒間待機してから「さようなら」と表示します。
import time
print("こんにちは")
time.sleep(2) # 2秒間プログラムを一時停止
print("さようなら")
# 出力:
# こんにちは
# (2秒後)
# さようなら
カウントダウンタイマーの作成
sleep関数を使用してカウントダウンタイマーを作成する例です。このコードは10から1までカウントダウンし、各数字の間に1秒の間隔を設けています。
import time
print("カウントダウン開始")
for i in range(10, 0, -1):
print(i)
time.sleep(1) # 1秒間待機
print("カウントダウン終了")
# 出力:
# カウントダウン開始
# 10
# 9
# 8
# ...
# 1
# カウントダウン終了
注意点
精度の問題
sleep関数は指定した時間だけプログラムを停止しようとしますが、オペレーティングシステムのスケジューリングやシステムの負荷によって、実際の停止時間は指定した時間と完全に一致しない場合があります。特に短い時間(ミリ秒単位)での精度を求める場合は注意が必要です。
以下のコードは、sleep関数の精度を確認する例です。
import time
start_time = time.time()
time.sleep(0.01) # 10ミリ秒の停止を指定
end_time = time.time()
actual_sleep_time = (end_time - start_time) * 1000 # ミリ秒に変換
print(f"指定した停止時間: 10 ミリ秒")
print(f"実際の停止時間: {actual_sleep_time:.2f} ミリ秒")
# 出力例:
# 指定した停止時間: 10 ミリ秒
# 実際の停止時間: 11.63 ミリ秒
このコードを実行すると、指定した時間と実際の停止時間に差があることが確認できます。この差はシステムの状態によって変動します。
ブロッキング操作
sleep関数はブロッキング操作です。つまり、sleep関数が実行されている間、プログラムの他の部分は実行されません。マルチスレッドプログラムでは、一つのスレッドでsleep関数を使用しても、他のスレッドは影響を受けずに実行を続けます。
以下は、マルチスレッドでsleep関数を使用した例です。
import time
import threading
def task_with_sleep():
print("スレッド1: 開始")
time.sleep(2) # 2秒間停止
print("スレッド1: 終了")
def another_task():
print("スレッド2: 開始")
print("スレッド2: 処理中...")
print("スレッド2: 終了")
# スレッド1でsleep関数を実行
thread1 = threading.Thread(target=task_with_sleep)
# スレッド2で別のタスクを実行
thread2 = threading.Thread(target=another_task)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
# 出力例:
# スレッド1: 開始
# スレッド2: 開始
# スレッド2: 処理中...
# スレッド2: 終了
# スレッド1: 終了
この例では、スレッド1がsleep関数で停止している間も、スレッド2は影響を受けずに実行を続けることがわかります。
例外処理との関係
sleep関数の実行中に例外が発生した場合、sleep関数は中断され、例外処理が行われます。以下は、sleep関数実行中にキーボード割り込み(Ctrl+C)が発生した場合の例です。
import time
try:
print("5秒間のsleepを開始します。Ctrl+Cで中断してください...")
time.sleep(5)
print("sleepが完了しました")
except KeyboardInterrupt:
print("\nsleepが中断されました")
# 出力例(Ctrl+Cで中断した場合):
# 5秒間のsleepを開始します。Ctrl+Cで中断してください...
# sleep中断されました
このコードは、sleep関数実行中にキーボード割り込みが発生すると、sleep関数が中断され、例外処理ブロックが実行されることを示しています。
代替手段
より高度なタイミング制御や非同期処理が必要な場合は、asyncioモジュールのasyncio.sleep()関数やスケジューリングライブラリ(scheduleなど)の使用を検討するとよいでしょう。
asyncio.sleep()とtime.sleepの違い
time.sleep()は同期的な関数で、呼び出されるとプログラムの実行を完全に停止させます。一方、asyncio.sleep()は非同期関数で、プログラムの実行を停止させずに他の非同期タスクを実行することができます。
以下はasyncio.sleep()を使用した例です。このコードでは複数のタスクを同時に実行し、それぞれが独立して待機することができます。
import asyncio
async def task1():
print("タスク1: 開始")
await asyncio.sleep(2) # 2秒間待機(他のタスクが実行可能)
print("タスク1: 完了")
async def task2():
print("タスク2: 開始")
await asyncio.sleep(1) # 1秒間待機(他のタスクが実行可能)
print("タスク2: 完了")
async def main():
# 両方のタスクを同時に実行
await asyncio.gather(task1(), task2())
# メインプログラム
asyncio.run(main())
# 出力:
# タスク1: 開始
# タスク2: 開始
# タスク2: 完了
# タスク1: 完了
このコードでは、task1とtask2が同時に開始され、task2が先に完了し、その後task1が完了します。time.sleep()を使用した場合、タスク1が完全に終了するまでタスク2は開始されません。
asyncio.sleep()の主な利点:
- 非ブロッキング:他のタスクが実行可能
- 効率的なリソース使用:待機中にCPUリソースを解放
- 複雑な非同期処理に適している
一方、time.sleep()は単純な遅延が必要な場合や、マルチスレッドを使用しない同期プログラムに適しています。
まとめ
Pythonのsleep関数は、プログラムの実行を一時的に停止させるシンプルな機能です。基本的な使い方は非常に簡単ですが、カウントダウンタイマーなど、様々な場面で活用することができます。
ただし、精度の問題やブロッキング操作であることなど、いくつかの注意点も理解しておく必要があります。より高度なタイミング制御が必要な場合は、他のモジュールやライブラリの使用も検討してみてください。