Class: Mutex
- Inherits:
-
Object
- Object
- Mutex
- Defined in:
- lib/thread.rb,
thread.c
Overview
Mutex implements a simple semaphore that can be used to coordinate access to shared data from multiple concurrent threads.
Example:
require 'thread'
semaphore = Mutex.new
a = Thread.new {
semaphore.synchronize {
# access shared resource
}
}
b = Thread.new {
semaphore.synchronize {
# access shared resource
}
}
Instance Method Summary collapse
-
#exclusive_unlock { ... } ⇒ Object
If the mutex is locked, unlocks the mutex, wakes one waiting thread, and yields in a critical section.
-
#initialize ⇒ Mutex
constructor
Creates a new Mutex.
-
#lock ⇒ Object
Attempts to grab the lock and waits if it isn't available.
-
#locked? ⇒ Object
Returns
true
if this lock is currently held by some thread. - #marshal_dump ⇒ Object
-
#marshal_load ⇒ Object
for marshalling mutexes and condvars.
-
#synchronize { ... } ⇒ Object
Obtains a lock, runs the block, and releases the lock when the block completes.
-
#try_lock ⇒ Object
Attempts to obtain the lock and returns immediately.
-
#unlock ⇒ Object
Releases the lock.
Constructor Details
#initialize ⇒ Mutex
Creates a new Mutex
60 61 62 63 64 65 |
# File 'lib/thread.rb', line 60 def initialize @waiting = [] @locked = false; @waiting.taint # enable tainted comunication self.taint end |
Instance Method Details
#exclusive_unlock { ... } ⇒ Object
If the mutex is locked, unlocks the mutex, wakes one waiting thread, and yields in a critical section.
140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/thread.rb', line 140 def exclusive_unlock return unless @locked Thread.exclusive do @locked = false begin t = @waiting.shift t.wakeup if t rescue ThreadError retry end yield end self end |
#lock ⇒ Object
Attempts to grab the lock and waits if it isn't available.
92 93 94 95 96 97 98 99 100 |
# File 'lib/thread.rb', line 92 def lock while (Thread.critical = true; @locked) @waiting.push Thread.current Thread.stop end @locked = true Thread.critical = false self end |
#locked? ⇒ Object
Returns true
if this lock is currently held by some thread.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/thread.rb', line 70
/*
* Document-method: locked?
* call-seq: locked?
*
* Returns +true+ if this lock is currently held by some thread.
*
*/
static VALUE
rb_mutex_locked_p(VALUE self)
{
Mutex *mutex;
Data_Get_Struct(self, Mutex, mutex);
return MUTEX_LOCKED_P(mutex) ? Qtrue : Qfalse;
}
|
#marshal_dump ⇒ Object
#marshal_load ⇒ Object
for marshalling mutexes and condvars
|
# File 'thread.c'
/* for marshalling mutexes and condvars */
static VALUE
dummy_load(VALUE self, VALUE string)
{
return Qnil;
}
|
#synchronize { ... } ⇒ Object
Obtains a lock, runs the block, and releases the lock when the block completes. See the example under Mutex.
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/thread.rb', line 127
/*
* Document-method: synchronize
* call-seq: synchronize { ... }
*
* Obtains a lock, runs the block, and releases the lock when the block
* completes. See the example under Mutex.
*
*/
static VALUE
rb_mutex_synchronize(VALUE self)
{
rb_mutex_lock(self);
return rb_ensure(rb_yield, Qundef, rb_mutex_unlock, self);
}
|
#try_lock ⇒ Object
Attempts to obtain the lock and returns immediately. Returns true
if the lock was granted.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/thread.rb', line 78
/*
* Document-method: try_lock
* call-seq: try_lock
*
* Attempts to obtain the lock and returns immediately. Returns +true+ if the
* lock was granted.
*
*/
static VALUE
rb_mutex_try_lock(VALUE self)
{
Mutex *mutex;
Data_Get_Struct(self, Mutex, mutex);
if (MUTEX_LOCKED_P(mutex))
return Qfalse;
mutex->owner = rb_thread_current();
return Qtrue;
}
|
#unlock ⇒ Object
Releases the lock. Returns nil
if ref wasn't locked.
105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/thread.rb', line 105 def unlock return unless @locked Thread.critical = true @locked = false begin t = @waiting.shift t.wakeup if t rescue ThreadError retry end Thread.critical = false begin t.run if t rescue ThreadError end self end |