Как работает прослушиватель событий?

Во время одной из моих лекций о Unity мы обсудили обновление позиции игрока, проверив каждый кадр, если пользователь нажал кнопку. Кто-то сказал, что это неэффективно, и вместо этого мы должны использовать прослушиватель событий.

Мой вопрос: независимо от языка программирования или ситуации, в которой он применяется, как работает прослушиватель событий?

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

На основе обсуждения в классе кажется, что прослушиватель событий работает по-другому.

Как работает прослушиватель событий?

119 голосов | спросил Gary Holiday 4 Jam1000000amThu, 04 Jan 2018 07:22:03 +030018 2018, 07:22:03

11 ответов


136

В отличие от представленного вами опроса (где кнопка проверяется каждый кадр), прослушиватель событий не проверяет, нажата ли кнопка вообще. Вместо этого он вызывается, когда кнопка нажата.

Возможно, термин «слушатель событий» бросает вас. Этот термин предполагает, что «слушатель» активно делает что-то для прослушивания, когда на самом деле он вообще ничего не делает. «Слушатель» - это просто функция или метод, которые подписываются на событие. Когда событие срабатывает, вызывается метод слушателя («обработчик событий»).

Преимущество шаблона события заключается в том, что нет никакой стоимости, пока кнопка не будет нажата. Событие можно обрабатывать таким образом, чтобы он не отслеживался, потому что он исходит из того, что мы называем «аппаратным прерыванием», что ненадолго предает запущенный код для запуска события.

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

ответил Robert Harvey 4 Jam1000000amThu, 04 Jan 2018 07:29:42 +030018 2018, 07:29:42
51

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

Система событий реализуется с использованием объектов событий, которые управляют списком подписчиков. Заинтересованные объекты (называемые подписчики , слушатели , делегаты и т. Д.) Могут подписаться, чтобы получать информацию о событии, вызвав метод, который подписывается к событию, которое заставляет событие добавлять их в свой список. Всякий раз, когда событие запущено (терминология также может включать: , называемый , запущенный , вызывается , запускать и т. д.), он вызывает соответствующий метод для каждого из подписчиков, чтобы сообщить им о событии, передавая любую контекстуальную информацию, необходимую им для понимания того, что произошло.

ответил Alexander 4 Jam1000000amThu, 04 Jan 2018 09:38:33 +030018 2018, 09:38:33
36

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

Более длинное объяснение немного более важно.

Откуда происходят клиентские события?

Каждое современное приложение â € имеет внутренний, обычно полускрытый «цикл событий», который отправляет события в правильные компоненты, которые должны их получать. Например, событие «клик» отправляется на кнопку, поверхность которой видна в текущих координатах мыши. Это на самом простом уровне. На самом деле ОС выполняет большую часть этой диспетчеризации, поскольку некоторые события и некоторые компоненты будут получать сообщения напрямую.

Откуда происходят события приложения?

Операционные системы отправляют события по мере их возникновения. Они делают это реактивно, сообщая своим водителям.

Как драйверы генерируют события?

Я не эксперт, но наверняка некоторые из них используют прерывания процессора: аппаратное обеспечение, которое они контролируют, поднимает вывод на CPU при наличии новых данных; CPU запускает драйвер, который обрабатывает входящие данные, которые в конечном итоге генерируют (очередь) событий для отправки, а затем возвращают управление обратно в ОС.

Итак, как вы видите, ваше приложение на самом деле не работает все время. Это куча процедур, которые запускаются ОС (sorta), когда происходят события, но ничего не делает в остальное время.


â € имеются заметные исключения, например. игры за один раз, которые могли бы поступить иначе

ответил Sklivvz 4 Jpm1000000pmThu, 04 Jan 2018 12:17:42 +030018 2018, 12:17:42
18

Терминология

  • событие : тип вещи, который может произойти.

  • срабатывание событий : конкретное событие события; событие происходит.

  • прослушиватель событий : что-то, что ищет события.

  • обработчик событий . То, что происходит, когда прослушиватель событий обнаруживает срабатывание события.

  • подписчик событий : ответ, который должен вызвать обработчик событий.

Эти определения не зависят от реализации, поэтому они могут быть реализованы по-разному.

Некоторые из этих терминов обычно ошибочно принимают за синонимы, поскольку пользователям часто не нужно различать их.

Общие сценарии

  1. Программирование-логические события.

    • Событие - это когда вызывается какой-то метод.

    • Событие - это особый вызов этого метода.

    • Слушатель событий - это крючок в методе событий, который вызывается при каждом запуске события, который вызывает обработчик события.

    • Обработчик событий вызывает коллекцию подписчиков событий.

    • Абонент (ы) выполняет любые действия (ы), которые система означает, что они происходят в ответ на возникновение события.

  2. Внешние события.

    • Событие - это внешнее событие, которое может быть выведено из наблюдаемых.

    • срабатывает событие , когда это внешнее событие может быть распознано как имеющееся.

    • Слушатель событий каким-то образом обнаруживает срабатывания событий, часто путем опроса наблюдаемых (s), затем он вызывает обработчик события при обнаружении срабатывания события.

    • Обработчик событий вызывает коллекцию подписчиков событий.

    • Абонент (ы) выполняет любые действия (ы), которые система означает, что они происходят в ответ на возникновение события.

Опрос против вставки крючков в механизм обстрела события

Пункт, сделанный другими, заключается в том, что опрос часто не требуется. Это связано с тем, что прослушиватели событий могут быть реализованы за счет того, что события firings автоматически вызывают обработчик событий, что часто является наиболее эффективным способом реализации событий, когда события происходят на системном уровне.

По аналогии, вам не нужно каждый день проверять почтовый ящик на почту, если почтовый работник стучит в вашу дверь и направляет почту прямо вам.

Однако прослушиватели событий также могут работать с помощью опроса. Опрос не обязательно должен проверять определенное значение или другое наблюдаемое; это может быть более сложным. Но, в целом, точка опроса заключается в том, чтобы вывести, когда произошло какое-то событие, чтобы на него можно было ответить.

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

Логика цепочки событий

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

Это потому, что для вас работает опрос. Например, Windows проверяет такие вещи, как изменения состояния клавиатуры, и если она обнаружит ее, она вызовет подписчиков событий. Итак, когда вы подписываетесь на событие нажатия на клавиатуру, вы фактически подписываетесь на событие, которое является самим подписчиком на событие, которое опроса.

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


  

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

     

На основе обсуждения в классе кажется, что прослушиватель событий работает по-другому.

     

Как работает прослушиватель событий?

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

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

Обновление: при низкоуровневом аппаратном опросе

Оказывается, USB-устройства и другие современные протоколы связи имеют довольно увлекательный набор протоколов взаимодействия для взаимодействия, позволяя устройствам ввода-вывода, включая клавиатуры и мыши, участвовать в топологиях ad hoc .

Интересно, что « прерывания » являются довольно императивными, синхронными вещами, поэтому они не обрабатывают сетевые топологии ad hoc . Чтобы исправить это, « interruptts » были обобщены на асинхронные высокоприоритетные пакеты, называемые " транзакциями прерывания " (в контексте USB) или " прерывания с сообщением " ( в контексте PCI). Этот протокол описан в спецификации USB:

  

 введите описание изображения здесь>> </a> </p>
  
  <p> - "Спецификация универсальной последовательной шины, версия 2.0" , печатная страница-222; PDF-страница-250 (2000-04-27)

Судя по всему, устройства ввода /вывода и компоненты связи (например, USB-концентраторы) в основном действуют как сетевые устройства. Таким образом, они отправляют сообщения, которые требуют опроса их портов и т. Д. Это уменьшает потребность в выделенных аппаратных линиях.

Операционные системы, подобные Windows, как представляется, обрабатывают сам процесс опроса, например. как описано в документации MSDN для USB_ENDPOINT_DESCRIPTOR , в котором описано, как часто контролировать Windows с помощью хост-контроллера USB для прерывания /изохронных сообщений:

  

Значение bInterval содержит интервал опроса для прерываний и изохронных конечных точек. Для других типов конечных точек это значение следует игнорировать. Это значение отражает конфигурацию устройства в прошивке. Драйверы не могут его изменить.

     

Интервал опроса, а также скорость устройства и тип хост-контроллера определяют частоту, с которой драйвер должен инициировать прерывание или изохронную передачу. Значение в bInterval не представляет фиксированного количества времени. Это относительная величина, и фактическая частота опроса также будет зависеть от того, работают ли устройство и хост-контроллер USB с низкой, полной или высокой скоростью.

     

- "Структура USB_ENDPOINT_DESCRIPTOR" , Hardware Dev Center,Microsoft

Новые протоколы подключения монитора, такие как DisplayPort , похоже, делают то же самое:

  

Транспортировка с несколькими потоками (MST)

     
  • MST (Multi-Stream Transport) добавлен в DisplayPort Ver.1.2

         
    • В Ver.1.1a
    • доступен только SST (однопоточный транспорт)   
  •   
  • MST переносит несколько потоков A /V на один разъем

         
    • До 63 потоков; а не «Стим на одну дорожку»

           
      • Никакой синхронности, принятой среди перевозимых потоков; один поток может находиться в периоде гашения, тогда как другие не являются
      •   
    •   
    • Транспорт, ориентированный на соединение

           
      • Путь от источника потока к потоку целевого потока, установленного посредством транзакций сообщений через AUX CHʼs до начала передачи потока.

      •   
      • Добавление /удаление потока без влияния на оставшиеся потоки

      •   
    •   
  •   

 введите описание изображения здесь>> </a> </p>
  
  <p> -Slide <sup> # </sup> 14 из <a href = " Обзор DisplayPortTM Ver.1.2 " (2010-12-06)

Эта абстракция позволяет использовать некоторые опрятные функции, например, запустить 3 монитора из одного соединения:

  

DisplayPort Multi-Stream Transport также позволяет объединять три или более устройства вместе, но в противоположной, менее «потребительской» ориентации: одновременное управление несколькими дисплеями с одного выходного порта.

     

- «DisplayPort» , Википедия

Концептуально, точка, отбирающая от этого, заключается в том, что механизмы опроса позволяют использовать более обобщенные последовательные коммуникации, что является удивительным, когда вы хотите получить более общую функциональность. Таким образом, аппаратное обеспечение и ОС делают много опросов для логической системы. Затем потребители, которые подписываются на события, могут пользоваться теми деталями, которые обрабатываются для них системой нижнего уровня, без необходимости писать свои собственные протоколы опроса /передачи сообщений.

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

ответил Nat 4 Jpm1000000pmThu, 04 Jan 2018 13:04:49 +030018 2018, 13:04:49
8

Pull vs Push

Существуют две основные стратегии для проверки того, произошло ли событие или достигнуто определенное состояние. Например, представьте, что вы ожидаете важной доставки:

  • Pull : каждые 10 минут, спуститесь к своему почтовому ящику и проверьте, доставлен ли он,
  • Нажмите : сообщите парню доставки, чтобы позвонить вам, когда он будет выполнять доставку.

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

С другой стороны, подход push , как правило, более эффективен: ваш код запускается только тогда, когда ему что-то нужно делать. С другой стороны, это требует наличия механизма для регистрации регистратора /наблюдателя /обратного вызова 1 .

1 К сожалению, у моего почтового менеджера, как правило, отсутствует такой механизм.

ответил Matthieu M. 4 Jpm1000000pmThu, 04 Jan 2018 18:36:56 +030018 2018, 18:36:56
1

О единстве в конкретном - нет другого способа проверки ввода игрока, кроме опроса каждого кадра. Чтобы создать прослушиватель событий, вам понадобится объект, например «система событий» или «диспетчер событий», чтобы сделать опрос, поэтому он только подтолкнет проблему к другому классу.

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

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

ответил Dunno 4 Jpm1000000pmThu, 04 Jan 2018 15:50:08 +030018 2018, 15:50:08
1

Если у вас нет поддержки в вашей ОС /Framework, которая обрабатывает события, такие как нажатие кнопки или переполнение таймера или приход сообщения, вам придется реализовать этот сеанс прослушивателя событий, используя опрос в любом случае (где-то внизу).

Но не отвратитесь от этого шаблона дизайна только потому, что вы сразу не получаете преимущество в производительности. Вот причины, по которым вы должны использовать его независимо от того, есть ли у вас основа для поддержки обработки событий или нет.

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

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

ответил OpalApps 4 Jpm1000000pmThu, 04 Jan 2018 15:52:35 +030018 2018, 15:52:35
1

Большинство циклов событий построены над некоторыми примитивами мультиплексирования опроса, предоставляемыми операционной системой. В Linux этот примитив часто является poll (2) (но может быть старый select)). В приложениях с графическим интерфейсом сервер отображения (например, Xorg или Wayland ) сообщает (через сокет ( 7) или pipe (7) ) с вашей заявкой. Читайте также о X Window System Protocols and Architecture .

Такие примитивы опроса эффективны; ядро на практике пробудит ваш процесс, когда будет выполнен некоторый ввод (и обрабатывается некоторое прерывание).

Конкретно, ваша библиотека widget toolkit взаимодействует с вашим сервером отображения, ожидает сообщений и отправьте эти сообщения своим виджетам. Библиотеки инструментальных средств, такие как Qt или GTK довольно сложны (миллионы строк исходного кода). Ваша клавиатура и мышь обрабатываются только процессом сервера отображения (который преобразует такие входы в сообщения событий, отправленные клиентским приложениям).

(я упрощаю, на самом деле вещи намного сложнее)

ответил Basile Starynkevitch 4 Jpm1000000pmThu, 04 Jan 2018 23:49:31 +030018 2018, 23:49:31
1

В системе, основанной исключительно на опросе, подсистема, которая может захотеть узнать, когда произойдет какое-либо конкретное действие, должна будет запускать некоторый код в любое время, когда это может произойти. Если есть много подсистем, каждый из которых должен реагировать в течение 10 м от какого-то не обязательно уникального события, все они должны будут проверить не менее 100 раз /секунду, произошло ли их событие. Если эти подсистемы обрабатываются в разных потоках (или, что еще хуже, процессов), которые требуют переключения в каждом таком потоке или процессе 100x /секунду.

Если многие из приложений, которые будут наблюдать за приложениями, скорее схожи, возможно, более эффективно иметь централизованную подсистему мониторинга - возможно, с таблицей, которая может наблюдать за многими вещами и наблюдать, изменились ли какие-либо из них. Например, если имеется 32 коммутатора, платформа может иметь функцию для считывания всех 32 переключателей сразу в слово, что позволяет коду монитора проверять, изменились ли какие-либо переключатели между опросами и - если нет - не беспокоиться о том, какой код может быть им интересен.

Если существует много подсистем, которые хотели бы получать уведомления, когда что-то изменится, наличие специальной подсистемы мониторинга уведомляет другие подсистемы о том, что события, которые они интересуют, могут быть более эффективными, чем подсчет каждой подсистемы собственных событий. Однако создание специализированной подсистемы мониторинга в тех случаях, когда никто не заинтересован ни в каких событиях, представляет собой чистую трату ресурсов. Если есть только несколько подсистем, которые заинтересованы в событиях, то затраты на их наблюдение за интересующими их событиями могут быть меньше, чем затраты на создание специализированной специализированной подсистемы мониторинга, но безубыточность точка будет сильно различаться между различными платформами.

ответил supercat 5 Jam1000000amFri, 05 Jan 2018 00:45:19 +030018 2018, 00:45:19
0

Слушатель событий как ухо ожидает сообщения. Когда событие происходит, подпрограмма, выбранная в качестве прослушивателя событий, работает с использованием аргументов события.

Всегда есть две важные данные: момент, когда происходит событие, и объект, где происходит это событие. Другим аргументом является больше данных о том, что произошло.

Слушатель событий указывает реакцию на происходящее.

ответил Rafael Marazuela 4 Jpm1000000pmThu, 04 Jan 2018 15:52:23 +030018 2018, 15:52:23
0

Слушатель событий следует шаблон публикации /подписки (как абонент)

В своей простейшей форме объект публикации поддерживает список инструкций подписчиков, которые должны выполняться, когда что-то нужно публиковать.

У него будет какой-то метод subscribe(x), где x зависит от того, как обработчик событий предназначен для обработки события. Когда вызывается подписка (x), x добавляется в список изданий подписчиков /ссылки подписчиков.

Издатель может содержать все, некоторые или никакие логические для обработки события. Это может просто потребовать ссылки на подписчиков, чтобы уведомлять /преобразовывать их с указанной логикой при возникновении события. Он может не содержать никакой логики и требовать объекты-подписчики (методы /прослушиватели событий), которые могут обрабатывать событие. Это, скорее всего, будет содержать смесь обоих.

Когда происходит событие, издатель будет перебирать и выполнять свою логику для каждого элемента в своем списке инструкций /ссылок подписчиков.

Независимо от того, насколько сложным выглядит обработчик событий, в его основе он следует этому простому шаблону.

Примеры

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

Для примера в реальном мире, когда вы подписываетесь на рассылку на Stack Exchange, ссылка на ваш профиль будет добавлена ​​в таблицу базы данных подписчиков. Когда пришло время опубликовать информационный бюллетень, ссылка будет использована для заполнения шаблона информационного бюллетеня, и он будет отправлен на ваш адрес электронной почты. В этом случае x является просто ссылкой на вас, и у издателя есть набор внутренних инструкций, используемых для всех подписчиков.

ответил Dom 7 Jpm1000000pmSun, 07 Jan 2018 16:08:16 +030018 2018, 16:08:16

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132