Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

Rubyでキューを使う方法!配列とQueueクラスの実装例を徹底解説

キューとは?

キュー(queue)とは、いわば「待ち行列」のことです。最新のApple製品を買うために並ぶ行列、映画のチケット売り場、スーパーのレジ待ち——こうした日常の「順番待ち」こそがキューです。

Rubyのプロジェクトでも、このキューを活用できます。

どのように使うのか?

キューは先に入ったものから順に処理される(FIFO:First-In-First-Out)仕組みのため、「待っている時間が長いものほど優先的に処理したい」という場面で特に役立ちます。

具体的な活用例:

  • 現実世界の待ち行列(レジの順番待ちなど)をプログラムでモデル化する
  • 幅優先探索(BFS)などのアルゴリズムを実装する
  • CPU、ディスク、プリンターなど、共有リソースへのアクセス制御を行う

それでは…

実際のコードを見ていきましょう!

配列でキューを実装する方法

Rubyでは、適切なメソッドを使えば配列をそのままQueueのように扱えます。

使うメソッドは次の2つ:

  • unshift(Ruby 2.5以降ではprependも使用可能)
  • pop

unshiftを使うと、キューに要素を1つ追加できます。

例:

queue = []

queue.unshift "apple"
queue.unshift "orange"
queue.unshift "banana"

# ["banana", "orange", "apple"]

一方、popはキューの末尾から要素を取り除きます。取り除かれるのは「次に処理すべき要素」です。

例:

queue.pop
# "apple"

queue.pop
# "orange"

また、要素を取り除かずに「次は何が来るのか」を確認したい場合は、末尾の要素を参照します。

例:

queue[-1]

# "banana"

この操作はpeek(覗き見)と呼ばれます。

スレッドセーフなQueueクラスを使う

Rubyには、マルチスレッド環境で安全に使える本格的なQueueクラスが標準で用意されています。このクラスはスレッドセーフかつブロッキング動作をするため、マルチスレッドプログラムでの作業分担に最適です。

例:

que = Queue.new

que << 1
que << 2
que << 3

キューから要素を取り出すにはpopを使います。

que.pop
# 1

que.pop
# 2

ここで重要なのが「ブロック」の挙動です。キューが空の状態でpopを呼び出すと、現在のスレッドはスリープし、新しい要素が追加されるまで待機します。これが「ブロックする」という意味です。

ブロックせずに即座に結果を得たい場合は、poptrueを渡します。

que.pop(true)

この場合、キューが空だとThreadError: queue emptyという例外が発生します。

SizedQueueでサイズ制限付きキューを作る

SizedQueueは、通常のキューにサイズ上限を加えたものです。

例:

que = SizedQueue.new(5)

キューが満杯の状態でpush<<と同じ操作)を実行すると、現在のスレッドは一時停止し、キューから要素が取り出されるまで待機します。

例:

que.push(:bacon)

待機する代わりに例外を発生させたい場合は、引数にtrueを渡します。

que.push(:bacon, true)

この場合、ThreadError: queue fullが発生します。

動画チュートリアル

まとめ

今回はRubyにおけるキューについて学びました!

タスクをFIFO(先入れ先出し)の順序で処理したいときにキューは便利です。キューの実装方法は主に2つあります。1つは配列とunshift/popを組み合わせるシンプルな方法、もう1つは標準ライブラリのQueueクラスを使う方法です。マルチスレッド環境では後者の利用が断然おすすめです。

最後まで読んでいただきありがとうございました。🙂


  1. Rubyのエイリアス(別名定義)完全ガイド:aliasキーワードとalias_methodの違い

    Rubyでは、既存のメソッドに別名(エイリアス)を付ける方法が2つあります。 alias(キーワード) alias_method(メソッド) どちらも同じ目的で使えますが、挙動が微妙に異なるため、初心者にとって混乱しやすいトピックです。 本記事では、両者の違いを詳しく掘り下げ、しっかりと理解できるように解説していきます。 aliasキーワードとは まずはaliasから見ていきましょう。aliasはRubyのキーワードの一つです(ifやdef、classなどと同じ扱いです)。 基本的な書き方は以下の通りです。 alias print_something puts print_someth

  2. RubyのStructとOpenStructの使い方を徹底解説!値オブジェクトを簡単に作る方法

    Rubyには、関連する属性をまとめて保持する「値オブジェクト」を手軽に作れるStructという組み込みクラスが用意されています。本記事では、Structの基本的な使い方から注意点、そしてOpenStructとの違いまで詳しく解説します。 そもそもStructとは何か? StructはRubyに組み込まれたクラスで、新しいクラスを動的に生成し、値オブジェクト(Value Object)を作成するために使われます。値オブジェクトとは、関連性のある複数の属性をひとまとめにして扱うためのオブジェクトです。 具体例を挙げてみましょう。 2つの座標(xとy)を持つPointというデータを表したい場合、この