今回、一定間隔ごと(10秒ごと、1分ごと)にプログラムを実行するコードを書こうとしてかなり悪戦苦闘したので、それをブログ記事にしようと思います。もともと作ろうとしていたのは、複数の仮想通貨取引所のAPIから仮想通貨の売買価格をとって、それをJSONなり、DBなりに保存しようとするものです。time
モジュールのtime.sleep
関数を使えば楽じゃないかと思いますが、これを使うと「プログラミング時間+スリープ時間(time.sleep
関数で指定した時間)」で実行されていくため、厳密な間隔での実行になりきらないという問題点があります。この問題を解決するのに、意外に時間がかかったというところです。で、この問題の解法として、今回threading
モジュールを利用しました。コードは以下になります。
import time, threading
def timekeep(): #インターバル用関数
time.sleep(5)
def func1(): #実行したい関数①
current_time = time.time()
print('func1')
def func2(): #実行したい関数②
current_time = time.time()
print('func2')
funcs = [timekeep, func1, func2] #実行したい関数の集合
threads = []
current_time = time.time()
for i in range(1, 6):
for func in funcs:
t = threading.Thread(target=func)
t.start()
threads.append(t)
for t in threads:
t.join()
print(str(i) + '回目: ' + str(time.time() - current_time))
threading
モジュールは、複数の関数や処理を「並列」して行うことができるようにするモジュールです。このthreading
モジュールで以下の3つの関数を並列で実行しています。
関数①: timekeep
関数
関数②: func1
関数
関数③: func2
関数
そして、threding.join()
関数とtimekeep
関数を用いて、timekeep
関数の処理が完了するまで、つまり指定した時間が経過するまで他の関数(func1
関数とfunc2
関数)は次のループ処理へと進みません。また、timekeep
関数を一番最初に実行する関数に指定しておくことで、他の関数の実行時間が合間に入ってくることも避けています。実行結果は以下になります。
func1 func2 1回目: 5.005943059921265 func1 func2 2回目: 10.008951187133789 func1func2 3回目: 15.011608123779297 func1 func2 4回目: 20.017914295196533 func1 func2 5回目: 25.020419120788574
APIから定期的に情報を取るコードを現在作成中なので、また改めて書こうと思います。主要参考サイトは以下になります。読んでくださった方、ありがとうございました。