Типичный интерфейс условных переменных (conditional variable) выглядит следующим образом:
Отличие условной переменной от мьютекса в том, что при использовании мьютекса вызывающий разблокировку должен быть тем же, кто его заблокировал. В то время как условная переменная может быть уведомлена любым источником. Кроме того, мьютекс требует, чтобы каждая операция lock сопровождалась операцией unlock, а условная переменная позволяет многократно вызывать notify, но гарантирует, что количество выполнений потоков, ожидавших через wait, не превысит количество вызовов notify.
После добавления условной переменной к входному потоку, поток, вызвавший sys_read
, может перейти в состояние ожидания и не будет выбран планировщиком, что позволит избежать ненужного использования ресурсов процессора.
Чтобы продолжить использование существующего алгоритма планирования без значительных изменений, мы создаём отдельный «спящий» раздел для пула потоков, который изолирован от планировщика. Когда поток переходит в состояние ожидания, он удаляется из планировщика, чтобы предотвратить его последующее ненужное пробуждение.
pub struct Processor {
/// Текущий выполняемый поток
current_thread: Option<Arc<Thread>>,
/// Планировщик, отслеживающий активные потоки
scheduler: SchedulerImpl<Arc<Thread>>,
/// Спящие потоки
sleeping_threads: HashSet<Arc<Thread>>,
}
Условные переменные используются в структурах, связанных с ожиданием и пробуждением, таких как входные потоки. Условная переменная хранит все потоки, ожидающие её.
#[derive(Default)]
pub struct Condvar {
/// Все потоки, ожидающие эту условную переменную
watchers: Mutex<VecDeque<Arc<Thread>>>,
}
Когда поток вызывает sys_read
и буфер пуст, он добавляется к watcher
условной переменной и удаляется из активных потоков в Processor
. Когда происходит прерывание клавиатуры и символы считываются, поток возвращается в планировщик для следующего вызова.
Открытое размышление: что произойдёт, если несколько потоков одновременно ожидают ввода? Есть ли решение этой проблемы?
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )