【保存版】Pythonのqueueモジュールを使いこなす|実例付き

※本サイトにはプロモーション・広告が含まれています。

(最終更新月:2023年6月)

✔当記事が対象とする読者

「PythonのQueueって何だろうか?」

「PythonのQueueの使い方を学びたい」

「PythonのQueueを活用した実例を確認したい」

✔当記事で伝える内容

  • PythonのQueueの概要
  • PythonのQueueの使い方とその応用
  • PythonのQueueを活用した具体例

当記事では、PythonのQueueの基本概念から始め、さまざまなオプションを駆使した応用方法までを、具体例を交えながら詳細に解説しています。

ぜひ最後までお読みください。

筆者プロフィール

筆者プロフィールアイコン

【現職】プロダクトマネージャー

【副業】ブログ(月間20万PV)/YouTube/Web・アプリ制作

「プログラミング × ライティング × 営業」の経験を活かし、30後半からのIT系職へシフト。現在はプロダクトマネージャーとして、さまざまな関係者の間に入り奮闘してます。当サイトでは、実際に手を動かせるWebアプリの開発を通じて、プログラミングはもちろん、IT職に必要な情報を提供していきます。

【当ブログで紹介しているサイト】

当サイトチュートリアルで作成したデモ版日報アプリ

Django × Reactで開発したツール系Webアプリ

✔人に見せても恥ずかしくないコードを書こう

「リーダブルコード」は、わかりやすく良いコードの定義を教えてくれる本です。

  • 見るからにきれいなコードの書き方
  • コードの分割方法
  • 変数や関数の命名規則

エンジニアのスタンダートとすべき基準を一から解説しています。

何回も読むのに値する本なので、ぜひ手にとって読んでみてください。

キュー:基本概念と種類

こちらでは、キューの基本的な概念と、それに関連するさまざまな種類について解説します。

PythonのQueueモジュールに限らず、一般的なQueueの概念について理解しましょう。

  • FIFOキュー(先入れ先出し)
  • LIFOキュー(後入れ先出し)
  • 優先度付きキュー

FIFOキュー(先入れ先出し)

FIFO(First In, First Out)キューは、最も一般的なキューの形式です。

この形式では、キューに最初に追加された要素が最初に取り出されます

人々が行列に並んで待つ様子に似ており、最初に来た人が最初にサービスを受けるという考え方です。

例えば、プリンターのジョブキューは通常、FIFO方式で処理されます。

LIFOキュー(後入れ先出し)

LIFO(Last In, First Out)キューは、スタックとも呼ばれ、最後に追加された要素が最初に取り出されるデータ構造です。

これは一般的に、物事を積み重ねていくイメージに近いでしょう。

たとえば、皿を積み重ねていった場合、最後に追加された皿(一番上)が最初に取り出されます。

優先度付きキュー

優先度付きキューでは、各要素が一定の優先度を持っているもの。

優先度が高い要素が最初に取り出されるのが特徴です。

一般的な生活の中で例を挙げると、病院の緊急室での患者の処理がこれに相当します。

患者は到着順ではなく、病状の重さ(つまり「優先度」)に基づいて処理されます。

Queueモジュール:主要なクラスとメソッド

Queueモジュール内には、キューを操作するための多くのクラスとメソッドが存在します。

ここでは、その主要なものを紹介します。

  • Queueモジュールのインポート
  • キューの生成(Queueクラス)
  • キューへの要素追加(putメソッド)
  • キューからの要素取り出し(getメソッド)
  • キューの要素数を数える
  • メソッド一覧

Queueモジュールのインポート

PythonのQueueモジュールを使用するためには、まずそれをインポートする必要があります。

以下がそのインポート方法です。

import queue

これにより、Queueモジュール内のクラスや関数を利用できるようになります。

確かめたい方はこちらをどうぞ。

>>> queue
<module 'queue' from '/usr/lib/python3.8/queue.py'>

キューの生成(Queueクラス)

Queueモジュールには、キューを作成するためのQueueクラスが含まれています。

Queueクラスをインスタンス化することで、新たなキューの作成が可能です。

q = queue.Queue()

この時点でqは空のFIFOキューとなり、これ以降で追加した要素を保存できます。

キューへの要素追加(putメソッド)

Queueクラスのインスタンスに対して、putメソッドを使うことで新たな要素をキューの末尾に追加できます。

puメソッドの引数に追加したい要素を指定してください。

q.put("apple")

このコードにより、文字列"apple"がキューqに追加されます。

キューからの要素取り出し(getメソッド)

キューから要素を取り出すには、getメソッドを使いましょう。

getメソッドはキューから最初の要素(FIFOキューの場合は最も古い要素)を削除し、その要素を返します。

item = q.get()

このコードにより、キューqから最初の要素が取り出され、その要素が変数itemに代入されます。

キューの要素数を数える

キューの要素数を数えるには、qsizeというメソッドがあります。

いくつのキューが格納されているかを数えられるメソッドです。

q.put('test1')
q.qsize()

#出力
#1

q.get()
#出力
#'test1'

q.qsize()
#出力
#0

メソッド一覧

以下は、queueモジュールのメソッドの一覧です。

メソッド名説明
all_tasks_done()全てのタスクが完了したかどうかを判定するif q.all_tasks_done():
empty()キューが空かどうかを判定するif q.empty():
full()キューが満杯かどうかを判定するif q.full():
get()キューからアイテムを取得するitem = q.get()
get_nowait()キューからアイテムを取得する(非ブロッキング)item = q.get_nowait()
join()キュー内の全てのタスクが完了するまでブロックするq.join()
maxsizeキューの最大サイズq.maxsize
mutexキューのロックオブジェクトq.mutex
not_emptyキューが空でないことを示す条件変数q.not_empty
not_fullキューが満杯でないことを示す条件変数q.not_full
put(item)アイテムをキューに追加するq.put(10)
put_nowait(item)アイテムをキューに追加する(非ブロッキング)q.put_nowait(20)
qsize()キュー内のアイテム数を取得するsize = q.qsize()
queueキューオブジェクトq = queue.Queue()
task_done()ワーカースレッドがタスクの完了を示すために呼び出すq.task_done()
unfinished_tasks完了していないタスク数q.unfinished_tasks

これらのメソッドを使用することで、queueモジュールを効果的に操作することができます。

実践:Queueモジュールの使い方

ここでは、具体的なコード例を通じて、Queueモジュールの使い方を具体的に見ていきましょう。

  • FIFOキューのサンプルコード
  • LIFOキューのサンプルコード

FIFOキューのサンプルコード

以下に、Queueモジュールを使ってFIFOキューを操作する基本的なコードを示します。

import queue

# FIFOキューの生成
q = queue.Queue()

# キューへの要素追加
q.put("apple")
q.put("banana")
q.put("cherry")

# キューからの要素取り出し
while not q.empty():
    print(q.get())

このコードを実行すると、"apple", "banana", "cherry"の順番で要素が取り出され、それぞれが表示されます。

LIFOキューのサンプルコード

次に、QueueモジュールのLifoQueueクラスを使ってLIFOキューを操作する基本的なコードを示します。

import queue

# LIFOキューの生成
q = queue.LifoQueue()

# キューへの要素追加
q.put("apple")
q.put("banana")
q.put("cherry")

# キューからの要素取り出し
while not q.empty():
    print(q.get())

このコードを実行すると、"cherry", "banana", "apple"の順番で要素が取り出され、それぞれが表示されます。

これは、最後に追加した要素から順に取り出されているためです。

PythonのQueueモジュールとマルチスレッド

Queueモジュールは、Pythonのマルチスレッド環境でも安全にデータを交換するために使用できます。

次の節ではその詳細を見ていきましょう。

  • マルチスレッドでキューを使う利点
  • マルチスレッドでのキューの利用例

マルチスレッドでキューを使う利点

Queueモジュールを活用すると、スレッド間でデータを安全にやり取りできるようになります。

なぜならマルチスレッドでのデータの競合や不整合に対して、データの待ち行列(キュー)を提供できるから。

ひとつのスレッドがキューにデータを入れ、他のスレッドでそのデータを取り出します。

結果としてデータは一度に一つのスレッドだけが扱うことになり、データの競合を防げるのです。

import queue
import threading

def producer(q, items):
    for item in items:
        q.put(item)
        print("Produced:", item)
    q.put(None)  # 終了を示すためにNoneを追加

def consumer(q):
    while True:
        item = q.get()
        if item is None:
            break  # 終了を示すNoneを取得したらループを終了
        print("Consumed:", item)

q = queue.Queue()  # スレッドセーフなキューオブジェクトの作成

# データを生産するスレッド
producer_thread = threading.Thread(target=producer, args=(q, [1, 2, 3, 4, 5]))
producer_thread.start()

# データを消費するスレッド
consumer_thread = threading.Thread(target=consumer, args=(q,))
consumer_thread.start()

producer_thread.join()
consumer_thread.join()

Queueモジュールのメソッドがスレッドセーフであるという特徴もあります。

複数のスレッドが同時にQueueオブジェクトのメソッドを呼び出しても、内部の状態が適切に保たれることを保証してくれるのです。

マルチスレッドでのキューの利用例

ここでは、マルチスレッド環境でキューを使用する簡単な例を紹介します。

ひとつのプロデューサースレッドがキューにデータを入れ、2つのコンシューマスレッドがキューからデータを取り出して処理します。

import queue
import threading

def producer(q, items):
    for item in items:
        q.put(item)
        print("Produced:", item)
    q.put(None)  # 終了を示すためにNoneを追加

def consumer(q):
    while True:
        item = q.get()
        if item is None:
            break  # 終了を示すNoneを取得したらループを終了
        print("Consumed:", item)

q = queue.Queue()  # スレッドセーフなキューオブジェクトの作成

# データを生産するスレッド
producer_thread = threading.Thread(target=producer, args=(q, [1, 2, 3, 4, 5]))
producer_thread.start()

# データを消費するスレッド
consumer_thread = threading.Thread(target=consumer, args=(q,))
consumer_thread.start()

producer_thread.join()
consumer_thread.join()

このコードを実行すると、プロデューサーが生産したデータが、コンシューマによって消費される様子を見ることができます。

まとめ

当記事では、PythonのQueueモジュールとその用途について学習してきました。

  • そもそもQueueとはなにか?
  • Pythonでのqueueモジュールの使い方
  • Queueクラスの書き方

この知識を活用することで、あなたのPythonプログラムのデータ管理がより効率的になるでしょう。

タイトルとURLをコピーしました