Подтвердить что ты не робот

Объясните шаблон "Лидер/Последователь"

Я не могу найти хорошее и доступное объяснение шаблона "Лидер/Последователь". Все объяснения либо просто относятся к нему в контексте некоторой проблемы, либо являются совершенно бессмысленно.

Может ли кто-нибудь объяснить механике, как работает этот шаблон, и почему и как он повышает производительность по сравнению с более традиционными асинхронными моделями ввода-вывода? Также приветствуются примеры и ссылки на диаграммы.

4b9b3361

Ответ 1

Как вы могли прочитать, шаблон состоит из 4 компонентов: ThreadPool, HandleSet, Handle, ConcreteEventHandler (реализует интерфейс EventHandler).

Вы можете думать о нем как о такси в ночное время, где все водители спят, кроме одного, лидера. ThreadPool - это станция, управляющая многими потоками - кабинами.

Лидер ожидает события ввода-вывода в HandleSet, например, как клиент ждет клиента.

Когда клиент приходит (в форме дескриптора, идентифицирующего событие ввода-вывода), водитель-лидер пробуждает еще одного водителя, чтобы стать следующим лидером и обслуживает запрос от своего пассажира.

Пока он берет клиента на данный адрес (вызывая ConcreteEventHandler и передавая ему Handle), следующий лидер может одновременно обслуживать другого пассажира.

Когда водитель закончит, он отвезет свое такси обратно на станцию ​​и заснет, если станция не пуста. В противном случае он становится лидером.

Плюсы для этого шаблона:

  • не требуется связь между потоками, отсутствие синхронизации, ни разделяемая память (без блокировок, мьютексов) необходимы.
  • больше ConcreteEventHandlers можно добавить, не затрагивая никаких других EventHandler
  • минимизирует задержку из-за нескольких потоков

Концы:

  • комплекс
  • сеть IO может быть узким местом

Ответ 2

Я хочу добавить ответ Джейка, связав другой PDF от того же автора, который описывает пример использования, когда они выбрали шаблон "Лидер/Последователь" над другими альтернативами: http://www.dre.vanderbilt.edu/~schmidt/PDF/OM-01.pdf

Ответ 4

Я думаю, что наиболее "ласковым" примером является phusian пассажир и приложение для рельсов. (Тип вводящего в заблуждение пассажира - фактически процесс apache mod_rails, который управляет многими рубиновыми приложениями, которые спали/припаркованы).

Итак, вы разрабатываете приложение для рельсов или приложение для синатры. Затем разверните его на веб-сервере с установленным пассажиром.

Лидер на самом деле является балансиром нагрузки пассажира. Пассажир - это кто-то, посетивший веб-страницу. Такси такси - это спящие экземпляры вашего приложения рельсов в пуле пассажирских устройств.

Когда вы устанавливаете этот пул равным 45 (database.yml в приложении rails). Ваше высказывание я хочу, чтобы 45 такси были готовы обслуживать веб-страницы. Когда кто-то посещает виртуальный хост-пассажир, делегат отправляет запрос одному из 45 ожидающих рельсовых приложений. Приложениям не нужно связываться с eachother, потому что все они подключены к одному и тому же брандмауэру базы данных (или множественное возможно также, если вы выполняете репликацию своих данных).

http://www.modrails.com/.

Приятно то, что даже если отдельные процессы могут потребовать времени для обработки запроса, общая система действительно эффективна/быстро, потому что у вас есть 45 из них, готовых обрабатывать запросы. Поэтому, даже если первое такси (приложение rails) не вернется от него (обслуживая запрошенную страницу), второй экземпляр ожидания в строке может использоваться для следующего запроса. Как только первый заканчивается, он также возвращается в очередь, и таким образом вы можете реагировать и легко загружать 4000+ pagereq./sec, хотя одно приложение-рельс может обрабатывать только 400 рек/сек. Конечно, есть ограничения (память и т.д. Для размера пула, иначе вы можете взять размер пула 200000 рельсовых приложений), но на практике это работает очень хорошо...