Python queue モジュール

Python では、queueモジュールは、マルチスレッドプログラミングで安全にデータを受け渡すためのスレッドセーフなキュー実装を提供します。

キューは先入れ先出し(FIFO)のデータ構造であり、queueモジュールは、複数のキュータイプを提供しています。例えばQueue、LifoQueueとPriorityQueueなど、さまざまなニーズを満たします。


キューの種類

1. Queue

Queueであるqueueモジュールで最も一般的に使用されるキュータイプであり、標準の先入れ先出し(FIFO)キューを実装しています。以下はQueueの基本的な使い方です:

例

import 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の基本的な使い方です:

例

import queue

# 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の基本的な使い方です:

例

import queue

# 優先度キューを作成
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 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キューが空/満杯のときにブロックするかどうかTrueq.get(block=False)
timeoutブロッキングのタイムアウト時間(秒)Noneq.put(x, timeout=5)

PriorityQueue 専用の使い方

要素の形式:(priority, data)。優先度が小さいほど先に取り出されます

例

pq = queue.PriorityQueue()
pq.put((1, "low"))
pq.put((0, "high"))
print(pq.get()[1])  # 出力: "high"

例

プロデューサー-コンシューマーモデル:

例

import queue, threading

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 = queue.PriorityQueue()
pq.put((3, "Scan"))
pq.put((1, "Emergency"))
pq.put((2, "Log"))

while not pq.empty():
    print(pq.get()[1])  # 出力順: Emergency → Log → Scan

非ブロッキング取得(デッドロック回避):

例

try:
    item = q.get_nowait()  # q.get(block=False) と同等
except queue.Empty:
    print(キューが空です)
その他の拡張