Ruby 2.4

Thread::Mutex

class Thread::Mutex

Parent:Object

Mutex

公共类别方法

new → mutex Show source

创建一个新的互斥体

static VALUE mutex_initialize(VALUE self) { return self; }

公共实例方法

lock → self Show source

试图抓住锁并等待它不可用。ThreadError如果mutex被当前线程锁定,则引发。

VALUE rb_mutex_lock(VALUE self) { rb_thread_t *th = GET_THREAD( rb_mutex_t *mutex; GetMutexPtr(self, mutex /* When running trap handler */ if (!mutex->allow_trap && th->interrupt_mask & TRAP_INTERRUPT_MASK) { rb_raise(rb_eThreadError, "can't be called from trap context" } if (rb_mutex_trylock(self) == Qfalse) { if (mutex->th == th) { rb_raise(rb_eThreadError, "deadlock; recursive locking" } while (mutex->th != th) { int interrupted; enum rb_thread_status prev_status = th->status; volatile int timeout_ms = 0; struct rb_unblock_callback oldubf; set_unblock_function(th, lock_interrupt, mutex, &oldubf, FALSE th->status = THREAD_STOPPED_FOREVER; th->locking_mutex = self; native_mutex_lock(&mutex->lock th->vm->sleeper++; /* * Carefully! while some contended threads are in lock_func(), * vm->sleepr is unstable value. we have to avoid both deadlock * and busy loop. */ if ((vm_living_thread_num(th->vm) == th->vm->sleeper) && !patrol_thread) { timeout_ms = 100; patrol_thread = th; } GVL_UNLOCK_BEGIN( interrupted = lock_func(th, mutex, (int)timeout_ms native_mutex_unlock(&mutex->lock GVL_UNLOCK_END( if (patrol_thread == th) patrol_thread = NULL; reset_unblock_function(th, &oldubf th->locking_mutex = Qfalse; if (mutex->th && interrupted == 2) { rb_check_deadlock(th->vm } if (th->status == THREAD_STOPPED_FOREVER) { th->status = prev_status; } th->vm->sleeper--; if (mutex->th == th) mutex_locked(th, self if (interrupted) { RUBY_VM_CHECK_INTS_BLOCKING(th } } } return self; }

locked? → true or false Show source

如果此锁当前由某个线程保存,则返回true

VALUE rb_mutex_locked_p(VALUE self) { rb_mutex_t *mutex; GetMutexPtr(self, mutex return mutex->th ? Qtrue : Qfalse; }

owned? → true or false Show source

如果此锁当前由当前线程保存,则返回true

VALUE rb_mutex_owned_p(VALUE self) { VALUE owned = Qfalse; rb_thread_t *th = GET_THREAD( rb_mutex_t *mutex; GetMutexPtr(self, mutex if (mutex->th == th) owned = Qtrue; return owned; }

sleep(timeout = nil) → number Show source

释放锁定,timeout如果给定,并且非零或永久,则会睡眠秒。ThreadError如果mutex未被当前线程锁定则引发。

当线程下一次被唤醒时,它将尝试重新获取锁。

请注意,此方法可以在没有明确的线程#唤醒调用的情况下唤醒。例如,接收信号等。

static VALUE mutex_sleep(int argc, VALUE *argv, VALUE self) { VALUE timeout; rb_scan_args(argc, argv, "01", &timeout return rb_mutex_sleep(self, timeout }

synchronize { ... } → result of the block Show source

获得一个锁,运行该块,并在块完成时释放锁。看下面的例子Mutex

static VALUE rb_mutex_synchronize_m(VALUE self, VALUE args) { if (!rb_block_given_p()) { rb_raise(rb_eThreadError, "must be called with a block" } return rb_mutex_synchronize(self, rb_yield, Qundef }

try_lock → true or false Show source

试图获得锁并立即返回。如果锁定被授予,则返回true

VALUE rb_mutex_trylock(VALUE self) { rb_mutex_t *mutex; VALUE locked = Qfalse; GetMutexPtr(self, mutex native_mutex_lock(&mutex->lock if (mutex->th == 0) { rb_thread_t *th = GET_THREAD( mutex->th = th; locked = Qtrue; mutex_locked(th, self } native_mutex_unlock(&mutex->lock return locked; }

unlock → self Show source

释放锁定。ThreadError如果mutex未被当前线程锁定则引发。

VALUE rb_mutex_unlock(VALUE self) { const char *err; rb_mutex_t *mutex; GetMutexPtr(self, mutex err = rb_mutex_unlock_th(mutex, GET_THREAD() if (err) rb_raise(rb_eThreadError, "%s", err return self; }