Class: ConditionVariable

Inherits:
Object
  • Object
show all
Defined in:
lib/thread.rb,
thread.c

Overview

ConditionVariable objects augment class Mutex. Using condition variables, it is possible to suspend while in the middle of a critical section until a resource becomes available.

Example:

require 'thread'

mutex = Mutex.new
resource = ConditionVariable.new

a = Thread.new {
  mutex.synchronize {
    # Thread 'a' now needs the resource
    resource.wait(mutex)
    # 'a' can now have the resource
  }
}

b = Thread.new {
  mutex.synchronize {
    # Thread 'b' has finished using the resource
    resource.signal
  }
}

Instance Method Summary collapse

Constructor Details

#initializeConditionVariable

Creates a new ConditionVariable



187
188
189
# File 'lib/thread.rb', line 187

def initialize
  @waiters = []
end

Instance Method Details

#broadcastObject

Wakes up all threads waiting for this condition.



220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/thread.rb', line 220

/*
 * Document-method: broadcast
 * call-seq: broadcast
 *
 * Wakes up all threads waiting for this condition.
 *
 */

static VALUE
rb_condvar_broadcast(VALUE self)
{
    ConditionVariable *condvar;

    Data_Get_Struct(self, ConditionVariable, condvar);
  
    thread_exclusive(wake_all, (VALUE)&condvar->waiting);
    rb_thread_schedule();

    return self;
}

#marshal_dumpObject

#marshal_loadObject

for marshalling mutexes and condvars



# File 'thread.c'

/* for marshalling mutexes and condvars */

static VALUE
dummy_load(VALUE self, VALUE string)
{
    return Qnil;
}

#signalObject

Wakes up the first thread in line waiting for this condition.



208
209
210
211
212
213
214
215
# File 'lib/thread.rb', line 208

def signal
  begin
    t = @waiters.shift
    t.run if t
  rescue ThreadError
    retry
  end
end

#waitObject

Releases the lock held in mutex and waits; reacquires the lock on wakeup.



194
195
196
197
198
199
200
201
202
203
# File 'lib/thread.rb', line 194

def wait(mutex)
  begin
    mutex.exclusive_unlock do
      @waiters.push(Thread.current)
      Thread.stop
    end
  ensure
    mutex.lock
  end
end