類別 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) → 數字或 nil 按一下以切換原始碼

釋放鎖定,並在提供且非 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;
}