类 Thread::Mutex

Thread::Mutex 实现了一个简单的信号量,可用于协调多个并发线程对共享数据的访问。

示例

semaphore = Thread::Mutex.new

a = Thread.new {
  semaphore.synchronize {
    # access shared resource
  }
}

b = Thread.new {
  semaphore.synchronize {
    # access shared resource
  }
}

公共类方法

Thread::Mutex.new → mutex 点击切换源代码

创建一个新的 Mutex

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

公共实例方法

lock → self 点击切换源代码

尝试获取锁,如果锁不可用则等待。如果当前线程已锁定 mutex,则会引发 ThreadError

VALUE
rb_mutex_lock(VALUE self)
{
    return do_mutex_lock(self, 1);
}
locked? → true 或 false 点击切换源代码

如果此锁当前被某个线程持有,则返回 true

VALUE
rb_mutex_locked_p(VALUE self)
{
    rb_mutex_t *mutex = mutex_ptr(self);

    return RBOOL(mutex->fiber);
}
owned? → true 或 false 点击切换源代码

如果此锁当前被当前线程持有,则返回 true

VALUE
rb_mutex_owned_p(VALUE self)
{
    rb_fiber_t *fiber = GET_EC()->fiber_ptr;
    rb_mutex_t *mutex = mutex_ptr(self);

    return mutex_owned_p(fiber, mutex);
}
sleep(timeout = nil) → number 或 nil 点击切换源代码

释放锁并休眠 timeout 秒(如果给出且非空)或永远休眠。如果当前线程未锁定 mutex,则会引发 ThreadError

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

请注意,此方法可以在没有显式 Thread#wakeup 调用时唤醒。例如,接收信号等。

如果被唤醒,则返回以秒为单位的休眠时间,如果超时,则返回 nil

static VALUE
mutex_sleep(int argc, VALUE *argv, VALUE self)
{
    VALUE timeout;

    timeout = rb_check_arity(argc, 0, 1) ? argv[0] : Qnil;
    return rb_mutex_sleep(self, timeout);
}
synchronize { ... } → 块的结果 点击切换源代码

获取锁,运行块,并在块完成时释放锁。请参阅Thread::Mutex下的示例。

static VALUE
rb_mutex_synchronize_m(VALUE self)
{
    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 或 false 点击切换源代码

尝试获取锁并立即返回。如果锁被授予,则返回true

VALUE
rb_mutex_trylock(VALUE self)
{
    rb_mutex_t *mutex = mutex_ptr(self);

    if (mutex->fiber == 0) {
        RUBY_DEBUG_LOG("%p ok", mutex);

        rb_fiber_t *fiber = GET_EC()->fiber_ptr;
        rb_thread_t *th = GET_THREAD();
        mutex->fiber = fiber;

        mutex_locked(th, self);
        return Qtrue;
    }
    else {
        RUBY_DEBUG_LOG("%p ng", mutex);
        return Qfalse;
    }
}
unlock → self 点击切换源代码

释放锁。如果mutex没有被当前线程锁定,则会引发ThreadError

VALUE
rb_mutex_unlock(VALUE self)
{
    const char *err;
    rb_mutex_t *mutex = mutex_ptr(self);
    rb_thread_t *th = GET_THREAD();

    err = rb_mutex_unlock_th(mutex, th, GET_EC()->fiber_ptr);
    if (err) rb_raise(rb_eThreadError, "%s", err);

    return self;
}