Событи́йно-ориенти́рованное программи́рование (; в дальнейшем СОП) — парадигма программирования, в которой выполнение программы определяется событиями — действиями пользователя (клавиатура, мышь, сенсорный экран), сообщениями других программ и потоков, событиями операционной системы (например, поступлением сетевого пакета).

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

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

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

Применение в серверных приложениях Событийно-ориентированное программирование применяется в серверных приложениях для решения проблемы масштабирования на 10000 одновременных соединений и более.

В серверах, построенных по модели «один поток на соединение», проблемы с масштабируемостью возникают по следующим причинам: слишком велики накладные расходы на структуры данных операционной системы, необходимые для описания одной задачи (сегмент состояния задачи, стек); слишком велики накладные расходы на переключение контекстов. Философской предпосылкой для отказа от потоковой модели серверов может служить высказывание Алана Кокса: «Компьютер — это конечный автомат. Потоковое программирование нужно тем, кто не умеет программировать конечные автоматы».

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

Мультиплексирование Для мультиплексирования соединений могут быть использованы следующие средства операционной системы: select (большинство UNIX систем). Плохо масштабируется, из-за того, что список дескрипторов представлен в виде битовой карты; poll и epoll (Linux); kqueue (FreeBSD); /dev/poll (Solaris); IO completion port (Windows); POSIX AIO на текущий момент только для операций дискового ввода-вывода; io submit и eventfd для операций дискового ввода-вывода.

Примеры реализаций Веб-серверы: Node.js nginx lighttpd Tornado Прокси-серверы: Squid

Применение в настольных приложениях В современных языках программирования события и обработчики событий являются центральным звеном реализации графического интерфейса пользователя. Рассмотрим, к примеру, взаимодействие программы с событиями от мыши. Нажатие правой клавиши мыши вызывает системное прерывание, запускающее определённую процедуру внутри операционной системы. В этой процедуре происходит поиск окна, находящегося под курсором мыши. Если окно найдено, то данное событие посылается в очередь обработки сообщений этого окна. Далее, в зависимости от типа окна, могут генерироваться дополнительные события. Например, если окно является кнопкой (в Windows все графические элементы являются окнами), то дополнительно генерируется событие нажатия на кнопку. Отличие последнего события в том, что оно более абстрактно, а именно, не содержит координат курсора, а говорит просто о том, что было произведено нажатие на данную кнопку.

Обработчик события может выглядеть следующим образом (на примере C#): private void button1_Click(object sender, EventArgs e)

MessageBox.Show("Была нажата кнопка");

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

Языки программирования В языке C# события реализованы как элемент языка и являются членами классов. Механизм событий здесь реализует шаблон проектирования Publisher/Subscriber. Пример объявления события: public class MyClass

public event EventHandler MyEvent;

Здесь EventHandler — делегат, определяющий тип процедуры обработчика событий. Подписка на событие производится следующим образом: myClass.MyEvent += new EventHandler(Handler); Здесь myClass — экземпляр класса MyClass, Handler — процедура-обработчик. Событие может иметь неограниченное количество обработчиков. При добавлении обработчика события он добавляется в специальный стек, а при возникновении события вызываются все обработчики по их порядку в стеке. Отписка от события, то есть удаление обработчика производится аналогично, но с использованием оператора «-=».

Разные языки программирования поддерживают СОП в разной степени. Наиболее полной поддержкой событий обладают следующие языки (неполный список): Perl (события и демоны DAEMON, и их приоритеты PRIO), Delphi (язык программирования), ActionScript 3.0, C# (события event), JavaScript (действия пользователя).

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

Инструменты и библиотеки

Node.js, событийно-ориентированный I/O фреймворк на JavaScript движке V8 Cocoa & Objective-C, рефлексивный объектно-ориентированный язык программирования, добавляющий сообщения в стиле Smalltalk в язык Си. GLib Gui4Cli, событийно-ориентированный язык программирования для Windows

libevent POCO libasync, часть библиотек sfs и sfslite, эффективная событийная библиотека для C++

AnyEvent, EV — модули на Perl для событийно-ориентированного программироания , компонентный событийно-ориентированный инструмент для Web-программирования на PHP 5 Tcl Twisted, Python Qt, кроссплатформенная библиотека виджетов для C++, основанная на модели управления событиями. Существует сокращённая версия, называемая Qt/Console, из которой исключён код поддержки виджетов, и представляющий собой управляемый событиями фреймворк, в который также включены некоторые дополнительные средства, вроде кроссплатформенной работы с сетью, многопоточности и работы с XML. QP — семейство открытых событийно-ориентированных окружений для встроенных систем реального времени Simple Unix Events a.k.a. SUE, простая объектно-ориентированная библиотека для построения событийно-ориентированных программ под Unix на языке C++.

См. также Автоматное программирование Callback (программирование)

Англоязычные источники описание из Portland Pattern Repository Event-Driven Programming: Introduction, Tutorial, History — учебное пособие Стефана Ферга (Stephen Ferg) Event Driven Programming учебное пособие Алана Голда (Alan Gauld) Martin Fowler. Event Collaboration Ben Watson. Transitioning from Structured to Event-Driven Programming Jonathan Simon. Rethinking Swing Threading Chris McDonald. The event driven programming style Christopher Diggins. Event Driven Programming using Template Specialization Stefan Schiffer and Joachim Hans Fröhlich. Concepts and Architecture of Vista — a Multiparadigm Programming Environment Event-Driven Programming and Agents LabWindows/CVI Resources Comment by Tim Boudreau Complex Event Processing and Service Oriented Architecture Event-driven programming and SOA: [http://soa-eda.blogspot.com/2006/11/how-eda-extends-soa-and-why-it-is.html Jack van Hoof. How EDA extends SOA and why it is important;;] Пример с открытым кодом: Distributed Publish/Subscribe Event System Событийно-ориентированное программирование на языке Java: Rex Youung. Jsasb

Материалы на русском

А. П. Полищук, С. А. Семериков. Программирование в X Window средствами Free Pascal

Ссылки

Категория:Парадигмы программирования