класс Thread::Mutex
Thread::Mutex реализует простой семафор, который можно использовать для координации доступа к общим данным из нескольких потоков.
Пример:
semaphore = Thread::Mutex.new
a = Thread.new {
semaphore.synchronize {
# access shared resource
}
}
b = Thread.new {
semaphore.synchronize {
# access shared resource
}
}
Публичные методы класса
static VALUE
mutex_initialize(VALUE self)
{
return self;
} Создаёт новый Mutex
Публичные методы экземпляра
VALUE
rb_mutex_lock(VALUE self)
{
return do_mutex_lock(self, 1);
} Пытается захватить блокировку и ждёт, если она недоступна. Выбрасывает ThreadError , если mutex была заблокирована текущим потоком.
VALUE
rb_mutex_locked_p(VALUE self)
{
rb_mutex_t *mutex = mutex_ptr(self);
return RBOOL(mutex->fiber);
} Возвращает 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);
} Возвращает true , если эта блокировка в данный момент удерживается текущим потоком.
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);
} Освобождает блокировку и спит timeout секунд, если это значение задано и не равно nil, или бесконечно. Выбрасывает ThreadError , если mutex не была заблокирована текущим потоком.
Когда поток вновь проснётся, он попытается повторно захватить блокировку.
Обратите внимание, что этот метод может проснуться без явного вызова Thread#wakeup. Например, при получении сигнала и т. д.
Возвращает время сна в секундах, если проснулся, или nil , если время истекло.
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);
} Получает блокировку, выполняет блок и освобождает блокировку по завершении блока. См. пример в разделе Thread::Mutex.
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;
}
} Пытается получить блокировку и возвращает результат немедленно. Возвращает true , если блокировка была предоставлена.
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;
} Освобождает блокировку. Выбрасывает ThreadError , если mutex не была заблокирована текущим потоком.
Ruby Core © 1993–2022 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.