среда, 18 июля 2007 г.

О моделях актеров

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


Модель актеров

Впервые модель актеров была предложена в работе «A Universal Modular ACTOR Formalism for Artificial Intelligence» тремя соавторами – Carl Hewitt, Peter Bishop, and Richard Steiger в 1973 году.

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

Актер – это вычислительная единица, которая в ответ на принятое сообщение может сделать следующее:
  • послать ограниченное количество сообщений другим актерам;
  • создать ограниченное количество новых актеров;
  • изменить способ реакции на последующие обрабатываемые сообщения.
Актер не должен делать никаких предположений относительно того, в какой последовательности поступают сообщения от других актеров.

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

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

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


Распределенная модель актеров (модель активных устройств)

С физической точки зрения распределенную сеть образуют устройства – персональные компьютеры, КПК, смартфоны, датчики, сенсоры и т.д. и т.п. Однако чтобы эти устройства могли взаимодействовать, необходимо ввести некоторую логическую модель. Назовем каждое устройство – узлом сети. В свою очередь каждый узел представляется единичным актером. Если одно устройство выставляет в сеть два и более актера, то оно считается за два и более узла соответственно. Важное ограничение для этого – внутреннее состояние одного актера никак не должно сказываться на внутреннем состоянии другого. Иначе это нарушит модель и приведет к труднопрогнозируемым побочным эффектам, так как модель постулирует, что влияние одного актера на другой может осуществляться только с помощью посылки сообщений. Конечно, никакими средствами из внешней среды невозможно гарантировать, что устройство предоставит два абсолютно независимых актера, но оно должно придерживаться данного правила, если необходима корректная работа всей системы.

При организации больших распределенных систем, либо систем с большим количеством актеров, устройства могут объединяться в логическую единицу – группу или кластер. Данный кластер будет выступать как единичный узел по отношению к актерам, находящимся за его пределами. Физически же будет выделен один узел, который будет взаимодействовать с внешним окружением с одной стороны, и с внутренней структурой кластера – с другой.

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

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

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

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

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


Локальная модель

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

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

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

Хочу подчеркнуть, что библиотека act-o реализует именно локальную модель актеров.


Направления исследований

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

среда, 11 июля 2007 г.

Планы на будущее

Что-ж, библиотека act-o развивается своим чередом, и настало время подумать о перспективах…

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

Сегодня я задался простым вопросом, а что такое кризис программирования? И Google в очередной раз пришел мне на помощь. Очень скоро я набрел на перевод статьи Эдсгера Дейкстры «Смиренный программист» (1972). Две небольшие цитата из статьи.

Но я назвал это второстепенной причиной; первостепенная же кроется в том, что... машины стали на несколько порядков мощнее! Говоря прямолинейно: пока машин не было вовсе, не существовало проблемы программирования; когда появились немногочисленные слабые компьютеры, программирование стало малозаметной проблемой; а теперь, когда у нас есть гигантские компьютеры, программирование само превратилось в гигантскую проблему. В этом смысле электронная промышленность не решила ни единой проблемы, она только породила их, создав проблему использования своей продукции. Другими словами, по мере того как мощность доступных машин выросла более чем в тысячу раз, стремление общества найти им применение выросло пропорционально, и бедный программист вынужден метаться буквально по минному полю. Возросшая мощь оборудования совместно с, возможно, еще более возросшей надежностью, сделали возможными решения, о которых программист даже не отваживался мечтать несколько лет назад. А теперь, спустя несколько лет, он должен мечтать о них и, более того, он обязан воплощать эти мечты в реальность! Удивительно ли, что мы оказались в кризисе программирования?

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


Обратите внимание на год публикации – 35 лет прошло. Думаете, что-то изменилось за это время?

Кризис как был, так и остался, и предлагается много способов создания больших программных систем, их разработки и описания. Но сколько я ни читал материалов, я ни разу не видел, чтобы автор задался вопросом: «А как нам вообще удается это делать?» Не помню, чтобы кто-то говорил, что необходимо обратиться к психологии, в частности к когнитивной психологии, чтобы исследовать способы, которыми человек вообще что-то описывает.

Я смотрю на это так. Программа – это описание системы. Разработка и проектирование – это в первую очередь мышление – это еще глубже в психологию и нейрофизиологию. А во вторую – это опять же описание проекта системы. И для процесса описания можно поставить три вопроса: Кто описывает? Что описывается? Как описывается? По-другому это можно перечислить, как – субъект, объект и способ. С объектом дела обстоят достаточно хорошо. Это как раз, классы алгоритмов, классы задача и классы систем. Подавляющее количество исследований проводится именно на эти темы. О субъекте – тишина. Остается способ. Это языки программирования и описания. Но способ – сущность зависимая. И зависит она от свойств субъекта и объекта. Но так как о субъекте никто не вспоминает, то можно констатировать только то, что способ – это здание с фундаментом наполовину.

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

Но это всё теория, а теперь немного о практике.

Теория об описании применима к любым программным системам и когда она появится, прорыв будет по многим фронтам, но меня больше интересуют мультиагентные системы, которые будут образовывать окружающие нас устройства, с целью сделать нашу жизнь приятной и комфортной. И как все знают, эти устройства будут самоадаптирующимися и интеллектуальными. Но они по определению не должны обладать настоящим интеллектом и тем более сознанием. Это очень просто – ваша микроволновка разогревает вам суп только потому, что у ней до сих пор нет интеллекта, а вот если бы он был, то она быстренько бы задалась вопросом: «А оно мне надо?» Скорее всего, это быстро превратится в апокалипсис на подобии того, о котором рассказывается в «Терминаторе»… Поэтому, экосистемы устройств всё равно придётся проектировать, конструировать и, в конечном счете, описывать.

В свою очередь эта часть обладает просто колоссальной практической значимостью. Когда мобильные устройства обмениваются только картинками и звуковыми файлами, то не страшно, если парочка из них сломается, либо начнет работать неправильно. Но когда от них начнет зависеть буквально всё – транспорт, системы охраны, жизнеобеспечения и даже кухня будет роботизированной, то любая ошибка потенциально может привести к человеческим жертвам. Это абсолютно недопустимо. И это будет кризис программирования даже не в квадрате, а в кубе…

Библиотека act-o тоже не будет забыта в ближайшее время. Как говорится: «Даже самый длинный путь начинается с одного маленького шага». Это хорошая база для того, чтобы получить начальное представление о мультиагентных системах.

Вы спросите: «А когда же начнется работа?». Так она уже идет, и будет продолжаться и впредь. И я буду рад сотрудничать с каждым, кто разделяет мое видение и готов работать над совместными проектами.
Оставайтесь на связи, и узнаете еще очень много интересного… :-)

понедельник, 9 июля 2007 г.

ООП в многопоточной среде: Введение

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

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

Чтобы избежать такой ситуации в Java, например, есть такой атрибут для методов как synchronized, а в языках С++ и Delphi таких атрибутов нет, и поэтому, необходимо код каждого публичного метода защищать критической секцией.
Мой опыт создания ядра библиотеки act-o говорит о том, что это очень плохая идея – писать программы в стиле ООП доступном на С++, защищая публичные методы критическими секциями. Потому, что почти сразу я столкнулся с явлением взаимоблокировки и разобраться, что и почему блокируется, было просто невозможно. Я отказался от ООП в пользу процедурного стиля.

Один из возможных способов избежать вышеописанных проблем – это вернуться к первоначальной концепции ООП, предложенной Аланом Кеем.
Алан Кей – это человек, который создал язык программирования Smalltalk, и ввел термин «объектно-ориентированный». Тогда он вкладывал в этот термин три основных идее:
  • Объект – базовая единица объектно-ориентированной системы.
  • Объекты могут обладать состоянием.
  • Посылка сообщений – единственный способ обмена информацией между объектами.
Для нас сейчас важен последний пункт – «посылка сообщений». Если организовать взаимодействие между объектами с помощью сообщений, а не через вызовы методов (как в C++), то удастся решить проблемы с инкапсуляцией и гонками. Только необходим настоящий обмен сообщениями – асинхронный, посредством организации очереди.

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

Все это краткое описание тех идей, на основе которых построена библиотека act-o, и именно такой механизм организации взаимодействия между объектами она предоставляет.

В недалеком будущем я опубликую небольшое исследование об истории ООП и о том, как оно от определения, данного Аланом Кеем, превратилось в то, чем оно является сейчас. Похоже, что модель актеров – это начальная идея ООП, но в новой обертке.
Также расскажу о таком понятии как Inversion of Control (IoC) и почему оно тоже может представлять проблему не только в многопоточном ООП, но и в классическом.
Оставайтесь на связи… :-)

четверг, 5 июля 2007 г.

«The act-o Library»

Это мой первый пост, и я рад, что это связанно с очень хорошей новостью. Мой проект «The act-o Library» наконец-то увидел свет. Сегодня я загрузил ее по адресу официального размещения http://sourceforge.net/projects/act-o Там же будут появляться и все последующие релизы пакетов.

«The act-o Library» или просто act-o – это библиотека классов на языке C++ и для программистов на языке C++, которая призвана помочь им в нелегком труде создания многопоточных приложений, с целью максимально задействовать потенциал современных многоядерных процессоров. В основу библиотеки положена модель актеров. Так как в ядро не закладывался функционал взаимодействия актеров на разных компьютерах или в разных процессах, то нет ни работы с сокетами, ни сериализации ни других подобных вещей. Поэтому, все получилось очезнь просто, компактно и быстро. А главное надежно, гарантированно и типобезопасно…

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

В ближайшее время я более подробно опишу, что вообще представляет собой библиотека act-o и ту модель, которая положена в основу библиотеки. И по ходу буду информировать вас обо всех существенных изменениях и событиях, связанных с библиотекой. Надеюсь, что она будет вам полезна.
Оставайтесь на связи… :-)