Letysite.ru

IT Новости с интернет пространства
1 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Событийная модель программирования

Событийно-ориентированное программирование

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

Сфера применения событийно-ориентированного программирования

Событийно-ориентированное программирование, как правило, применяется в следующих случаях:


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

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

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

В серверах, построенных по модели «один поток на соединение», проблемы с масштабируемостью возникают по следующим причинам:


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

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

Мультиплексирование в событийно-ориентированного программирования

Для мультиплексирования соединений могут быть использованы следующие средства операционной системы:


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

Примеры реализаций событийно-ориентированного программирования


    • Веб-серверы: Node.js, nginx, lighttpd
    • Прокси-серверы: Squid

Применение событийно-ориентированного программирования в настольных приложениях

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

Обработчик события может выглядеть следующим образом (на примере C#):

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

Языки событийно-ориентированного программирования

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

Здесь EventHandler — делегат, определяющий тип процедуры обработчика событий. Подписка на событие производится следующим образом:

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

Разные языки программирования поддерживают СОП в разной степени. Наиболее полной поддержкой событий обладают следующие языки (неполный список):


    • Perl (события и демоны DAEMON, и их приоритеты PRIO),
    • PHP
    • Java,
    • Delphi (язык программирования),
    • ActionScript 3.0,
    • C# (события event),
    • JavaScript (действия пользователя).

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

Блог сурового челябинского программиста

Are you aware how much time I’ve spent learning for details of Java? Thread management, dynamics, CORBA.

суббота, 29 августа 2009 г.

Событийная модель построения приложения

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

Большинство приложений в процессе своей работы постоянно реагируют на те или иные события. Это может быть щелчок пользователем по иконке, получение http-запроса, получение сигнала от датчика, завершение коммита транзакции и т.д. Реакция приложения проявляется в выполнении некоторых действий (отрисовка окна, отправка http-ответа, отправка сигнала исполнительному устройству, запуск BPEL-процесса и т.д.). Так вот, суть в том, что никто не мешает перенести такое поведение на уровень архитектуры приложения, т.е. организовав не только его внешнее поведение в соответствии с событийной моделью, но и внутреннее строение.

Кто работал с WinAPI или с Java Swing, тот должен быть хорошо знаком с такой моделью построения программы. В приложении есть некоторые агенты — события, которые генерируются в ответ на внешнее воздействие. Есть обработчики событий — код, который непосредственно делает что-то полезное. И есть то, что сводит гору и Магомета — диспетчер событий. Именно он вызывает те или иные обработчики в ответ на возникновение тех или иных событий.

Все приложение при этом строится в виде цикла обработки событий (в терминах WinAPI — цикл обработки сообщений, там события называются сообщениями).

Таким образом алгоритм работы приложения, основанного на событийной модели, следующий:

1. Зарегистрировать обработчики событий в диспетчере событий.
2. В ответ на внешнее воздействие сгенерировать событие.
3. Послать событие диспетчеру событий.
4. Диспетчер событий принимает событие и ищет для него обработчик (если тот зарегистрирован).
5. Диспетчер событий вызывает обработчик.
6. Перейти на пункт 2.

Причем вот что интересно: посылать событие диспетчеру и принимать его в нем можно асинхронно. Это позволяет распараллеливать процессы генерации и обработки событий. Для обмена событиями между такими процессами используется очередь событий.

В чем же здесь профит? Если еще раз представить себе систему, построенную на базе событийной модели, то становится понятно следующее:

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

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

3. Если обработчики одного и того же события независимы друг от друга — их можно очень легко параллелить. Обработчики разных событий можно параллелить почти всегда.

4. Так как код слабосвязан, то он хорошо ложится на модель распределенных вычислений. Т.е. обработчики событий можно разнести по отдельным узлам сети. Это — удобный момент при разработке приложения, которое должно работать на кластере.

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

А теперь слайды. Давайте бегло рассмотрим небольшой пример — http-сервер на Java. Пусть наш сервер будет принимать запросы от пользователей и генерировать событие в зависимости от типа запроса и расширения запрашиваемого файла. Далее, диспетчер событий будет искать зарегистрированные обработчики и вызывать их.

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

public class EventsQueue <

private static EventsQueue _instance = null ;

Лекция 12: Событийно управляемое программирование в .NET

Ключевым элементом для понимания природы взаимодействия объектов программы в среде вычислений является понятие события .

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

Ранее нами было рассмотрено понятие типа как совокупности объектов. Заметим, что произвольное семейство (действительных в нашем частном случае) объектов может быть параметризовано (или, иначе, концептуализировано) не только типами, но и событиями .

В соответствии со схемой двухуровневой концептуализации , оценивающее отображение ||.|| переводит индивид h- языка (в частности, языка программирования) в h . Затем возможный (потенциальный) индивид h из семейства возможных индивидов H переводится событием i из семейства соотнесений Asg в действительный индивид h(i) из семейства действительных индивидов Ui . Аналогично, следующий шаг преобразований, управляемый событием j из семейства Asg , переводит h(i) в состояние h(i)(j) (см. рис. 23.1).

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

Под событием в языке программирования обычно понимается способ внедрения того или иного фрагмента в программный код с целью изменения поведения программы.

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

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

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

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

После изложения понятийного аппарата концепции событийно управляемого программирования перейдем к вопросу реализации данного механизма применительно к языку объектно-ориентированного программирования C#.

В целях реализации механизма событий в языке программирования C# предусмотрен так называемый механизм делегатов .

Заметим, что механизм делегатов в языке C# является существенным усовершенствованием ранних подходов сходной функциональности в языках программирования C и C++, известных под названием функции обратного вызова ( callback function ), основанных на использовании малоинформативных и потенциально небезопасных указателей в оперативной памяти.

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

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

В качестве иллюстрации приведем описание типа- и переменной-делегата на языке С#:

Как видно из приведенного фрагмента программы, формально описание типов- и переменных-делегатов не отличается от традиционного описания методов и переменных.

Фундаментальное отличие переменной-делегата от ранее рассмотренных объектов языка C# состоит в том, что в качестве значения переменной-делегату можно присвоить метод. Проиллюстрируем это утверждение следующим фрагментом программы на языке C#:

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

Проиллюстрируем далее порядок вызова переменной-делегата следующим фрагментом программы на языке C#:

Как мы видим, означивание переменной-делегата greetings активизирует соотнесенный с ней на предыдущем шаге метод SayHello в соотнесении «John» с генерацией состояния «Hello from John» . Фактически данный пример изображает второй шаг концептуализации .

Для более наглядной иллюстрации работы механизма делегатов в языке программирования C# приведем пример фрагмента программы, характеризующего еще одно из соотнесений семейства для второго шага концептуализации :

Как видно из приведенного примера, переменная-делегат greetings типа Notifier может принимать в качестве значения любой из методов SayHello и SayGoodBye .

В данном случае, в отличие от предыдущего примера, значением, вычисляемым в ходе выполнения метода SayGoodBye , соотнесенного с переменной-делегатом greetings , является конкретизация «Good bye from John» , полученная на основе означивания SayGoodBye(«John») .

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

Для более подробного рассмотрения механизмов расширенного управления программой на языке C# посредством событий на основе делегатов , необходимо предварительно исследовать основные особенности переменных данного типа.

Прежде всего, следует отметить то обстоятельство, что переменные-делегаты могут иметь пустое значение null , что соответствует отсутствию назначенного им метода. Здесь проявляется аналогия с теорией вычислений Д. Скотта в том отношении, что любой домен непременно имеет неопределенное значение . Эта параллель наводит на предположение, что теория вычислений Д. Скотта способна адекватно формализовать событийно управляемое программирование . Оказывается, что это предположение весьма важно, а его исследование — продуктивно.

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

Еще одной особенностью переменных-делегатов является их принадлежность к классу объектов первого рода ( first class object ). Согласно правилам языка программирования C#, делегаты можно хранить в структурах данных, передавать как параметры и т.д.

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

Событийно-управляемое программирование

В основу Windows положен принцип событийного управления. Это значит, что и сама система, и приложения после запуска ожидают действий пользователя и реагируют наних заранее заданным образом. Любое действие пользователя (нажатие клавиши на клавиатуре, щелчок кнопкой мыши, перемещение мыши) называется событием. Структура программы, управляемой событиями, изобра­жена нарис. 14.1.

Рис. 14.1. Структура программы, управляемой событиями

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

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

Рис. 14.2. Структура Windows-приложения

Среда Visual Studio.NET содержит удобные средства разработки Windows-npи ложений, выполняющие вместо программиста рутинную работу — создание шаб лонов приложения и форм, заготовок обработчиков событий, организацию цик ла обработки сообщений и т. д. Рассмотрим эти средства.

Шаблон Windows-приложения

Создадим новый проект (File ► New ► Project), выбрав шаблон Windows Application (рис. 14.3). После более длительных раздумий, чем для консольного приложе­ния, среда сформирует шаблон Windows-приложения. Первое отличие, которое бросается в глаза, — вкладка заготовки формы Form1.cs[Design], расположенная в основной части экрана. Форма представляет собой окно и предназначена для размещения компонентов (элементов управления) — меню, текста, кнопок, спи­сков, изображений и т. д.

Рис. 14.3. Выбор шаблона проекта

Среда создает не только заготовку формы, но и шаблон текста приложения. Пе­рейти к нему можно, щелкнув в окне Solution Explorer (View ► Solution Explorer) правой кнопкой мыши на файле Form1.cs и выбрав в контекстном меню команду View Code. При этом откроется вкладка с кодом формы, который, за исключе­нием комментариев, приведен в листинге 14.1. Представлять себе, что написано в вашей программе, весьма полезно, поэтому давайте внимательно рассмотрим этот текст.

Листинг 14.1.Шаблон Windows-приложения

public class Form1 : System.Windows.Forms.Form

private System.ComponentModel.Container components = null;

protected override void Dispose(bool disposing)

if (components != null)

#region Windows Form Designer generated code

private void InitializeCompone()

this.components = new System.ComponentModel.Container();

this.Size = new System.Drawing.Size(300, 300);

static void Main()

Приложение начинается с директив использования пространств имен библиоте­ки .NET. Для пустой формы, не содержащей ни одного компонента, необходи­мыми являются только две директивы:

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

Список наиболее употребительных элементов этого пространства имен приведен в табл. 14.1, а часть иерархии — на рис. 14.4.

Объектно-событийные модели (в программировании)

Объектно-событийные модели (в программировании) — формализм представления сложных алгоритмических, информационных, порождающих и иных систем, заключающийся в присоединении к формальному сетевому графу продуцирующих или иным образом проявляющих активность объектов календаря событий, причем на каждой обработке события граф объектов реинтерпретируется снова по концепции, схожей с трактовкой сетевого графика работ. Важной особенностью является соблюдение всех трактовок объектно-ориентированного программирования к таким объектам, а также передача структурированной информации по дугам графа при исполнении активного события. Передача данных вне дуг осуществляется через глобальную ленту данных. Реальной предельной параллельной объектно-событийной моделью является процедура с планированием повторного входа, а ее теоретическим предельным случаем — расширенная машина Тьюринга, упомянутая далее.

[править] Теоретическая база (теория алгоритмов)

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

[править] Философские аспекты в теории вакуума

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

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

Несколько слов о гносеологическом аспекте данной темы. Идея дедуктивного вывода и трансформации ОСМ восходит к идеям материально-дуалистической трактовки в стиле информационизма и, отчасти, креационизма, но с упором на агностику. Примем за данное, что такая деятельность или идеальна и надсистемна (творец или создатель мировой событийной платформы в виде реконструируемого динамически по внутренним и обменным закономерностям отношения), что косвенно позволяет судить о ее логически прогностируемом характере, или имманентна мирозданию, что не требует надсистемных трактовок. Таким образом философский гилозоизм данной теории почти очевиден и лишь отчасти дает агностические трактовки в сфере идеального надсистемного. Категория надсистемного в свое время была введена в теории физического вакуума А. Е. Акимова.

[править] Литература

1. Пекунов В. В. Теория объектно-событийных моделей. Индукция, моделирование и синтез последовательных и параллельных программ. — LAP LAMBERT Academic Publishing, 2012. — 132 с. — ISBN 978-3-8484-4104-4.

2. Пекунов В. В. Метаслой моделирования алгоритма, данных и функциональных характеристик последовательных и параллельных программ // Информационные технологии.- 2011. — № 6. — С.51-56.

Читать еще:  Решение двойственной задачи линейного программирования онлайн
Ссылка на основную публикацию
Adblock
detector