Python queue モジュール
Python では、queueモジュールは、マルチスレッドプログラミングで安全にデータを受け渡すためのスレッドセーフなキュー実装を提供します。
キューは先入れ先出し(FIFO)のデータ構造であり、queueモジュールは、複数のキュータイプを提供しています。例えばQueue、LifoQueueとPriorityQueueなど、さまざまなニーズを満たします。
キューの種類
1. Queue
Queueであるqueueモジュールで最も一般的に使用されるキュータイプであり、標準の先入れ先出し(FIFO)キューを実装しています。以下はQueueの基本的な使い方です:
例
# キューを作成
q = queue.Queue()
# キューに要素を追加
q.put(1)
q.put(2)
q.put(3)
# キューから要素を取得
print(q.get()) # 出力: 1
print(q.get()) # 出力: 2
print(q.get()) # 出力: 3
2. LifoQueue
LifoQueueは、スタックに似た後入れ先出し(LIFO)キューです。以下はLifoQueueの基本的な使い方です:
例
# LIFO キューを作成
q = queue.LifoQueue()
# キューに要素を追加
q.put(1)
q.put(2)
q.put(3)
# キューから要素を取得
print(q.get()) # 出力: 3
print(q.get()) # 出力: 2
print(q.get()) # 出力: 1
3. PriorityQueue
PriorityQueueは、要素が優先度順に取り出される優先度キューです。以下はPriorityQueueの基本的な使い方です:
例
# 優先度キューを作成
q = queue.PriorityQueue()
# キューに要素を追加。要素はタプル (優先度, データ)
q.put((3, 'Low priority'))
q.put((1, 'High priority'))
q.put((2, 'Medium priority'))
# キューから要素を取得
print(q.get()) # 出力: (1, 'High priority')
print(q.get()) # 出力: (2, 'Medium priority')
print(q.get()) # 出力: (3, 'Low priority')
よく使うメソッド
1. put(item, block=True, timeout=None)
将 itemキューに入れます。もしblockためにTrueかつキューが満杯の場合は、timeout秒間待機し、キューに空きができるまで待ちます。もしtimeoutためにNoneの場合は、無限に待機します。
2. get(block=True, timeout=None)
キューから要素を取得して削除します。もしblockためにTrueかつキューが空の場合は、timeout秒間待機し、キューに要素が入るまで待ちます。もしtimeoutためにNoneの場合は、無限に待機します。
3. qsize()
キュー内の要素数を返します。
4. empty()
キューが空の場合は、Trueを返し、それ以外の場合はFalse。
5. full()
キューが満杯の場合は、Trueを返し、それ以外の場合はFalse。
スレッドセーフ
queueモジュールのすべてのキュータイプはスレッドセーフです。つまり、複数のスレッドが追加の同期メカニズムを必要とせずに、同じキューを安全に同時に操作できます。これにより、queueモジュールは、マルチスレッドプログラミングでデータを受け渡すための理想的な選択肢になります。
例:マルチスレッドキュー
以下は、Queueを使用してマルチスレッド間でデータを受け渡す例です:
例
import threading
import time
# キューを作成
q = queue.Queue()
# プロデューサースレッド
def producer():
for i in range(5):
print(f'生産 {i}')
q.put(i)
time.sleep(1)
# コンシューマースレッド
def consumer():
while True:
item = q.get()
if item is None:
break
print(f'消費 {item}')
q.task_done()
# プロデューサースレッドを起動
producer_thread = threading.Thread(target=producer)
producer_thread.start()
# コンシューマースレッドを起動
consumer_thread = threading.Thread(target=consumer)
consumer_thread.start()
# プロデューサースレッドの完了を待機
producer_thread.join()
# キュー内のすべてのタスクの完了を待機
q.join()
# 終了シグナルを送信
q.put(None)
consumer_thread.join()
一般的な属性とメソッド
以下は、Python queue モジュール(スレッドセーフキュー)でよく使われるクラス、メソッド、属性の表による説明です。機能の説明と例を含みます:
queue モジュールのコアクラス
| 类 | 説明 | 適用シーン |
|---|---|---|
queue.Queue | 先入れ先出し(FIFO)キュー | 一般的なタスクキュー |
queue.LifoQueue | 後入れ先出し(LIFO)キュー(スタックに類似) | 後入れ先出しが必要なシーン |
queue.PriorityQueue | 優先度キュー(最小ヒープ実装) | 優先度に応じてタスクを処理 |
queue.SimpleQueue | よりシンプルなFIFOキュー(Python 3.7+) | 高度な機能が不要なシーン |
共通メソッド(すべてのキュークラスでサポート)
| メソッド | 説明 | 例 | 戻り値 |
|---|---|---|---|
put(item) | 要素を入れる | q.put("task1") | None |
get() | 要素を取り出して削除する | item = q.get() | キューの要素 |
empty() | キューが空かどうかを判定 | if q.empty(): | True/False |
full() | キューが満杯かどうかを判定 | if q.full(): | True/False |
qsize() | キューの現在のサイズを返す | size = q.qsize() | 整数 |
task_done() | タスクの完了をマークする(join()) | q.task_done() | None |
join() | すべてのタスクが完了するまでブロック | q.join() | None |
ブロッキング制御パラメータ
| パラメータ | 説明 | デフォルト値 | 例 |
|---|---|---|---|
block | キューが空/満杯のときにブロックするかどうか | True | q.get(block=False) |
timeout | ブロッキングのタイムアウト時間(秒) | None | q.put(x, timeout=5) |
PriorityQueue 専用の使い方
要素の形式:(priority, data)。優先度が小さいほど先に取り出されます
例
pq.put((1, "low"))
pq.put((0, "high"))
print(pq.get()[1]) # 出力: "high"
例
プロデューサー-コンシューマーモデル:
例
q = queue.Queue(maxsize=3) # 容量3のキュー
def producer():
for i in range(5):
q.put(f"Task-{i}")
print(f"Produced: Task-{i}")
def consumer():
while True:
item = q.get()
print(f"Consumed: {item}")
q.task_done()
threading.Thread(target=producer, daemon=True).start()
threading.Thread(target=consumer, daemon=True).start()
q.join() # すべてのタスクの完了を待機
優先度タスクの処理:
例
pq.put((3, "Scan"))
pq.put((1, "Emergency"))
pq.put((2, "Log"))
while not pq.empty():
print(pq.get()[1]) # 出力順: Emergency → Log → Scan
非ブロッキング取得(デッドロック回避):
例
item = q.get_nowait() # q.get(block=False) と同等
except queue.Empty:
print(キューが空です)