Ruby 2.4参考手册
线 | Thread
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;
}
Ruby 是一种面向对象、命令式、函数式、动态的通用编程语言,是世界上最优美而巧妙的语言。
主页 | https://www.ruby-lang.org/ |
源码 | https://github.com/ruby/ruby |
版本 | 2.4 |
发布版本 | 2.4.1 |