переменные условия имеют очереди? - PullRequest
1 голос
/ 28 марта 2012

Я выполняю операцию ожидания условной переменной.У меня есть структура для моей переменной состояния.Пока что в моей структуре есть монитор, очередь и спин-блокировка.Но я не уверен, должна ли переменная условия иметь очередь сама по себе.Мое уведомление выглядит следующим образом:

 void uthread_cv_notify (uthread_cv_t* cv) {
     uthread_t* waiter_thread;
     spinlock_lock(&cv->spinlock);
     waiter_thread   = dequeue (&cv->waiter_queue);
     if(waiter_thread)
     {
        uthread_monitor_exit(cv->mon);
        uthread_stop(TS_BLOCKED);
        uthread_monitor_enter(cv->mon);
        spinlock_unlock(&cv->spinlock);
     }
} 

Но мне интересно, если в функции уведомления или в функции ожидания мне следует просто ставить в очередь и удалять из очереди ожидания монитора?

Ответы [ 2 ]

0 голосов
/ 29 марта 2012

Операция сигнала (которую вы называете уведомлением) не должна требовать ввода монитора. Это неэффективно.

Похоже, вы пытаетесь реализовать какую-то неуклюжую старомодную систему состояния / монитора, в которой вызывающий «уведомлять» должен находиться внутри монитора, и гарантируется, что, если поток ожидает, этот поток получает монитор до того, как «уведомить», вызывающий абонент возвращается к монитору. (И этот ожидающий поток также не должен иметь цикл, повторно проверяющий условие.)

Это может быть, как CAR Hoare первоначально описал мониторы и условия, но формализм нецелесообразен / неэффективен для современных многопроцессорных систем, а также для потоковых реализаций, которые не имеют такой роскоши, как чрезвычайно тесная интеграция с планировщиком низкого уровня (для иметь возможность точно контролировать, какой поток должен запускаться, когда нет, поэтому нет никаких гонок о том, кто первым получает мьютекс: например, чтобы иметь возможность передавать поток из одной очереди ожидания в другую и т. д.)

Обратите внимание, как вы расширяете критическую секцию монитора в операции spinlock_lock и операции dequeue. Ни один из них не относится к монитору. Спин-блокировка независима, и очередь защищена спин-блокировкой, а не монитором. Монитор должен защищать только общие переменные пользовательского кода (специальное атомарное свойство операции ожидания).

0 голосов
/ 29 марта 2012

Так зачем вам дополнительная очередь? Вы уже храните все темы, которые должны быть уведомлены.

Кроме того, вы, вероятно, хотите сделать что-то вроде этого:

void uthread_cv_notify (uthread_cv_t* cv) {
     uthread_t* waiter_thread;
     spinlock_lock(&cv->spinlock);
     waiter_thread   = dequeue (&cv->waiter_queue);
     if(waiter_thread)
     {
        uthread_monitor_exit(cv->mon);
        uthread_stop(TS_BLOCKED);
        uthread_monitor_enter(cv->mon);
     }
     spinlock_unlock(&cv->spinlock);
} 

Это обеспечит постоянную разблокировку спин-блокировки.

...