Skip to content

Instantly share code, notes, and snippets.

@fortune
Last active February 3, 2023 12:10
Show Gist options
  • Save fortune/b0cd0aaa6091bbd0e4612c9260980a80 to your computer and use it in GitHub Desktop.
Save fortune/b0cd0aaa6091bbd0e4612c9260980a80 to your computer and use it in GitHub Desktop.
threading モジュールと queue モジュールによるマルチスレッドのサンプル

threading モジュールと queue モジュールによるマルチスレッドのサンプル

multiprocessing モジュールではないので、マルチプロセスではない。したがって、Queue も標準ライブラリにある queue モジュールで構わない。

マルチスレッドのコードは、各スレッドから共有されるデータ構造は競合状態になることを避けるために適切な排他処理をする必要がある。これは、メインのコードだけでなく、 使用する外部ライブラリでも同じだ。すなわち、マルチスレッドのプログラムは、使用するライブラリまで含めてスレッドセーフでないといけない。ただ、共有するデータがないなら スレッドセーフでなくても安全だ(そうだよな)。

"""
標準ライブラリの queue モジュールと threading モジュールを使ったマルチスレッドのサンプルコード
メインスレッドで皿洗いのタスクを一皿ずつこなしていき、一枚洗い終えるごとに
それをキューに突っ込んでいく。
乾燥担当のスレッドがキューから一枚ずつタスクを取り出して乾燥させる。
キューが空になったら、終了する。
"""
import threading, queue
import time
def washer(dishes, dish_queue):
for dish in dishes:
print('Washing', dish, 'dish')
time.sleep(5)
dish_queue.put(dish)
def dryer(dish_queue):
while True:
dish = dish_queue.get() # キューからタスクを取り出す
print('thread: {}, Drying {} dish'.format(threading.current_thread(), dish))
time.sleep(10)
dish_queue.task_done() # 処理が済んだら、それをキューに知らせる
dish_queue = queue.Queue()
for n in range(2):
# 作成するスレッドはデーモンスレッドにする。
# これにより、メインスレッドが終了するとき、デーモンスレッドも強制終了される。
# スレッドは無限ループになっているので、こうしないとプログラムが終了しない。
dryer_thread = threading.Thread(target=dryer, args=(dish_queue,), daemon=True)
dryer_thread.start()
dishes = ['salad', 'bread', 'entree', 'desert', 'chicken', 'pork', 'beaf']
washer(dishes, dish_queue)
# キューが空になるまでブロックされ、空になったら復帰する。
# この時点でデーモンスレッドが強制終了されても安全だ。
dish_queue.join()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment