класс SizedQueue
Этот класс представляет очереди заданной ёмкости. Операция добавления может быть заблокирована, если ёмкость заполнена.
См. Очередь для примера работы SizedQueue.
Методы класса
static VALUE
rb_szqueue_initialize(VALUE self, VALUE vmax)
{
long max;
max = NUM2LONG(vmax);
if (max <= 0) {
rb_raise(rb_eArgError, "queue size must be positive");
}
RSTRUCT_SET(self, QUEUE_QUE, ary_buf_new());
RSTRUCT_SET(self, QUEUE_WAITERS, ary_buf_new());
RSTRUCT_SET(self, SZQUEUE_WAITERS, ary_buf_new());
RSTRUCT_SET(self, SZQUEUE_MAX, vmax);
return self;
} Создаёт очередь фиксированной длины с максимальной ёмкостью max.
Методы экземпляра
static VALUE
rb_szqueue_clear(VALUE self)
{
rb_ary_clear(GET_QUEUE_QUE(self));
wakeup_all_threads(GET_SZQUEUE_WAITERS(self));
return self;
} Удаляет все объекты из очереди.
static VALUE
rb_szqueue_close(VALUE self)
{
return queue_do_close(self, TRUE);
} Аналогично Queue#close.
Различие в поведении с ожидающими потоками добавления.
Если есть ожидающие потоки добавления, они прерываются путём поднятия исключения ClosedQueueError('queue closed').
static VALUE
rb_szqueue_max_get(VALUE self)
{
return GET_SZQUEUE_MAX(self);
} Возвращает максимальный размер очереди.
static VALUE
rb_szqueue_max_set(VALUE self, VALUE vmax)
{
long max = NUM2LONG(vmax), diff = 0;
VALUE t;
if (max <= 0) {
rb_raise(rb_eArgError, "queue size must be positive");
}
if ((unsigned long)max > GET_SZQUEUE_ULONGMAX(self)) {
diff = max - GET_SZQUEUE_ULONGMAX(self);
}
RSTRUCT_SET(self, SZQUEUE_MAX, vmax);
while (diff-- > 0 && !NIL_P(t = rb_ary_shift(GET_SZQUEUE_WAITERS(self)))) {
rb_thread_wakeup_alive(t);
}
return vmax;
} Устанавливает максимальный размер очереди на заданное number значение.
static VALUE
rb_szqueue_num_waiting(VALUE self)
{
long len = queue_num_waiting(self) + szqueue_num_waiting_producer(self);
return ULONG2NUM(len);
} Возвращает количество потоков, ожидающих в очереди.
static VALUE
rb_szqueue_pop(int argc, VALUE *argv, VALUE self)
{
int should_block = queue_pop_should_block(argc, argv);
return szqueue_do_pop(self, should_block);
} Извлекает данные из очереди.
Если очередь пуста, вызывающий поток приостанавливается до тех пор, пока данные не будут добавлены в очередь. Если non_block равно true, поток не приостанавливается, и ThreadError выбрасывается.
static VALUE
rb_szqueue_push(int argc, VALUE *argv, VALUE self)
{
struct waiting_delete args;
int should_block = szqueue_push_should_block(argc, argv);
args.waiting = GET_SZQUEUE_WAITERS(self);
args.th = rb_thread_current();
while (queue_length(self) >= GET_SZQUEUE_ULONGMAX(self)) {
if (!should_block) {
rb_raise(rb_eThreadError, "queue full");
}
else if (queue_closed_p(self)) {
goto closed;
}
else {
rb_ary_push(args.waiting, args.th);
rb_ensure(queue_sleep, Qfalse, queue_delete_from_waiting, (VALUE)&args);
}
}
if (queue_closed_p(self)) {
closed:
raise_closed_queue_error(self);
}
return queue_do_push(self, argv[0]);
} Добавляет object в очередь.
Если места в очереди нет, поток ожидает освобождения места, если non_block не равно true. Если non_block равно true, поток не приостанавливается, и ThreadError выбрасывается.
Ruby Core © 1993–2017 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.