ログイン中のQiita Team
ログイン中のチームがありません

Qiita Team にログイン
コミュニティ
OrganizationイベントアドベントカレンダーQiitadon (β)
サービス
Qiita JobsQiita ZineQiita Blog
Python
Python3
timer
71
どのような問題がありますか?

この記事は最終更新日から3年以上が経過しています。

投稿日

更新日

Pythonで一定時間ごとに処理を実行する

pythonで一定間隔ごとに処理をしたい場合、以下のように単純にsleepしてしまうと、一定間隔でなくなってしまう。

bad.py
import time

def worker():
    print(time.time())
    time.sleep(8)

interval = 5
while True:
    worker()
    time.sleep(interval)

実際にこの例だと5秒おきに実行したかったのに、13秒おきに実行されてしまう。

1518294594.6087666
1518294607.611248
1518294620.6149857

以下のようにベースとなる時間を決めてそこからの時間差分を考慮するとできる。

schedule.py
import time
import threading

def worker():
    print(time.time())
    time.sleep(8)

def schedule(interval, f, wait=True):
    base_time = time.time()
    next_time = 0
    while True:
        t = threading.Thread(target=f)
        t.start()
        if wait:
            t.join()
        next_time = ((base_time - time.time()) % interval) or interval
        time.sleep(next_time)

waitがTrueの場合、同時実行されるスレッドは1つのみとなり、待ち時間以内に処理が終わらなかったら次のタイムスロットまで待つ。
(この例だと、5秒以内に処理が終わらないので+5秒さらに待つ)

>>> schedule(5, worker)
1518295406.8357077
1518295416.849788
1518295426.8451777

waitがFalseの場合は、きっちり5秒ごとに実行される(複数スレッドになりうる)

>>> schedule(5, worker, False)
1518295478.5527058
1518295483.5534766
1518295488.5580828
ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
kurogelee

コメント

(編集済み)
リンクをコピー
このコメントを報告
next_time = ((base_time - time.time()) % interval) or interval

マイナス値(例:-3.895)の剰余を取り(例:1.105)、それが0の場合はintervalを返すのですね。

最初見た時に違和感がありましたが、納得できました。

CとPythonでmodulo(%)演算が違うのですね。
C | Python > マイナス値のmodulo(%)演算 > C:マイナスを返す | Python:プラスを返す

1
どのような問題がありますか?
あなたもコメントしてみませんか :)
ユーザー登録
すでにアカウントを持っている方はログイン
記事投稿イベント開催中
マイクロソフト認定資格を取得する際の学習方法や経験談、おすすめ学習リソースなどを紹介しよう!
~
71
どのような問題がありますか?
ユーザー登録して、Qiitaをもっと便利に使ってみませんか

この機能を利用するにはログインする必要があります。ログインするとさらに下記の機能が使えます。

  1. ユーザーやタグのフォロー機能であなたにマッチした記事をお届け
  2. ストック機能で便利な情報を後から効率的に読み返せる
ユーザー登録ログイン
ストックするカテゴリー