類別 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; }