# class Queue

The Queue class implements multi-producer, multi-consumer queues. It is especially useful in threaded programming when information must be exchanged safely between multiple threads. The Queue class implements all the required locking semantics.

The class implements FIFO type of queue. In a FIFO queue, the first tasks added are the first retrieved.

Example:

    queue = Queue.new

    producer = Thread.new do
      5.times do |i|
         sleep rand(i) # simulate expense
         queue << i
         puts "#{i} produced"
      end
    end

    consumer = Thread.new do
      5.times do |i|
         value = queue.pop
         sleep rand(i/2) # simulate expense
         puts "consumed #{value}"
      end
    end

### Public Class Methods

new() click to toggle source

Creates a new queue instance.

    static VALUE
    rb_queue_initialize(VALUE self)
    {
        struct rb_queue *q = queue_ptr(self);
        RB_OBJ_WRITE(self, &q->que, ary_buf_new());
        list_head_init(queue_waitq(q));
        return self;
    }

### Public Instance Methods

<<(p1)
Alias for: push
clear() click to toggle source

Removes all objects from the queue.

    static VALUE
    rb_queue_clear(VALUE self)
    {
        struct rb_queue *q = queue_ptr(self);

        rb_ary_clear(check_array(self, q->que));
        return self;
    }

close click to toggle source

Closes the queue. A closed queue cannot be re-opened.

After the call to close completes, the following are true:

- `closed?` will return true

- `close` will be ignored.

- calling enq/push/<< will raise an exception.

- when `empty?` is false, calling deq/pop/shift will return an object from the queue as usual.

ClosedQueueError is inherited from StopIteration, so that you can break loop block.

    Example:

        q = Queue.new
        Thread.new{
          while e = q.deq # wait for nil to break loop
            # ...
          end
        }
        q.close

    static VALUE
    rb_queue_close(VALUE self)
    {
        struct rb_queue *q = queue_ptr(self);

        if (!queue_closed_p(self)) {
            FL_SET(self, QUEUE_CLOSED);

            wakeup_all(queue_waitq(q));
        }

        return self;
    }

closed? click to toggle source

Returns `true` if the queue is closed.

    static VALUE
    rb_queue_closed_p(VALUE self)
    {
        return queue_closed_p(self) ? Qtrue : Qfalse;
    }

deq(*args)
Alias for: pop
empty? click to toggle source

Returns `true` if the queue is empty.

    static VALUE
    rb_queue_empty_p(VALUE self)
    {
        return queue_length(self, queue_ptr(self)) == 0 ? Qtrue : Qfalse;
    }

enq(p1)
Alias for: push
length click to toggle source
size

Returns the length of the queue.

    static VALUE
    rb_queue_length(VALUE self)
    {
        return LONG2NUM(queue_length(self, queue_ptr(self)));
    }

Also aliased as: size
num_waiting() click to toggle source

Returns the number of threads waiting on the queue.

    static VALUE
    rb_queue_num_waiting(VALUE self)
    {
        struct rb_queue *q = queue_ptr(self);

        return INT2NUM(q->num_waiting);
    }

pop(non_block=false) click to toggle source
deq(non_block=false)
shift(non_block=false)

Retrieves data from the queue.

If the queue is empty, the calling thread is suspended until data is pushed onto the queue. If `non_block` is true, the thread isn't suspended, and `ThreadError` is raised.

    static VALUE
    rb_queue_pop(int argc, VALUE *argv, VALUE self)
    {
        int should_block = queue_pop_should_block(argc, argv);
        return queue_do_pop(self, queue_ptr(self), should_block);
    }

Also aliased as: deq, shift
push(object) click to toggle source
enq(object)
<<(object)

Pushes the given `object` to the queue.

    static VALUE
    rb_queue_push(VALUE self, VALUE obj)
    {
        return queue_do_push(self, queue_ptr(self), obj);
    }

Also aliased as: enq, <<
shift(*args)
Alias for: pop
size()
Alias for: length