キューとスレッドを解説しますが、このページでPythonの技術情報というよりは、投資など実際の運用に使えるようにしたいと思います。
ですので、本来は多くの機能がありますが省いて簡素にしています
ここでは最終的にキューとスレッドを組み合わせて、並行処理をストレスなくできるようにしたいです。
キュー
キューは簡単に言えば、処理の箱のようなもので、その箱にデータなどが溜まっていきます。それを順番に取り出します。取り出し方は、先入れ後出しや先入れ先出しなどがありますが、ここでは先入れ先出しを紹介します。
queue
という標準ライブラリを使用します。標準ですのでインストールは不要です。
以下の3種類の関数ありますが、ここではQueue
のみをインポートします。
- Queue:先入れ先出し
- LifoQueue:先入れ後出し
- PriorityQueue:優先順位付き
from queue import Queue aaa = Queue() # aaaというキューを作成します。 for i in range(1,5): aaa.put(i) # aaaというキューにデータを蓄積します。 while not aaa.empty(): # aaaというキューのデータがなくなるまでループします。 print(aaa.get()) # aaaというキューからデータを取り出します。 # 1 # 2 # 3 # 4
スレッド
スレッドはそのままですが、並列処理ですね。
例えば、ルーティン処理でデータを取得・分析をしていて、ある条件が整った時に、ルーティンが止まらないよう、別の処理を並行して走らせるという感じでしょうか。
投資の世界では1秒もロスが許されない!?そんなシビアなシステムを作りたいものですね。。。
threading
という標準ライブラリを使用します。標準ですのでインストールは不要です。
import threading import time def bbb(): for i in range(1,5): print("thread" + str(i)) time.sleep(0.5) if __name__ == '__main__': thread = threading.Thread(target=bbb) # bbbという関数を処理するthreadというスレッドを作成します。 thread.start() # スレッドスタートさせます print("start") for i in range(1,5): print(i) time.sleep(1) # thread1start # 1 # thread2 # 2thread3 # thread4 # 3 # 4
多少、結果がわかりにくいですが、並列処理しているのをご理解頂けると思います。
スレッドの終了(強制終了)
thread.setDaemon(True)
とすると、本体のシステムでsys.exit()
やCtrl+C
が実行されると、スレッドを強制終了します。ただし、Jupyter Notebookではsys.exit()が使用できませんので注意してください。
import sys import threading import time def bbb(): while True: print("thread") time.sleep(1) thread = threading.Thread(target=bbb) # bbbという関数を処理するthreadというスレッドを作成します。 thread.setDaemon(True) # システムが終了すると強制的にスレッドを停止します。 thread.start() # スレッドスタートさせます time.sleep(3) sys.exit()
キューとスレッドで並列処理
これが本番です。キューとスレッドを組み合わせて並列処理を滞りなく処理ができます。
投資では、これを実現できれば、発注の遅延によるロスを減らせると思います。
ポイントは、関数bbb
のwhile = True
です。while not aaa.empty()
とすると、キューがなくなった場合に関数bbb
が終わってしまいます。while = True
として、スレッドを常に動作させてキューに溜まれば処理をするという風にしています。
from queue import Queue import threading import time def bbb(aaa): while True: print("thread" + aaa.get()) if __name__ == '__main__': aaa = Queue() thread = threading.Thread(target=bbb, args=(aaa,)) thread.start() print("start") for i in range(1,5): for j in range(1,5): s = str(i)+"-"+str(j) if j == 1: aaa.put(s) else: print(s) time.sleep(0.1) # start # 1-2thread1-1 # 1-3 # 1-4 # 2-2thread2-1 # 2-3 # 2-4 # 3-2thread3-1 # 3-3 # 3-4 # 4-2thread4-1 # 4-3 # 4-4